Purpose of Calling Function Without Brackets Python

What does it mean when the parentheses are omitted from a function call (supposing no arguments are necessary)?

As mentioned, functions and methods are first-class objects. You call them by throwing some parentheses (brackets) on the end. But it looks like you want some more motivation for why python even lets us do that. Why should we care if functions are first-class or not?

Sometimes you don't want to call them, you want to pass a reference to the callable itself.

from multiprocessing import Process
t = Process(target=my_long_running_function)

If you put brackets after the above, it runs your my_long_running_function in your main thread; hardly what you wanted! You wanted to give Process a reference to your callable that it will run itself in a new process.

Sometimes you just want to specify the callable and let something else...

def do_something(s):
return s[::-1].upper()

map(do_something,['hey','what up','yo'])
Out[3]: ['YEH', 'PU TAHW', 'OY']

(map in this case) fill in its arguments.

Maybe you just want to drop a bunch of callables into some collection, and fetch the one you want in a dynamic manner.

from operator import *

str_ops = {'<':lt,'>':gt,'==':eq} # etc
op = str_ops.get(my_operator)
if op:
result = op(lhs,rhs)

The above is one way to map string representations of operators onto their actual action.

Function calls with & without parentheses

Best way to start and to learn what is going on here, I guess is to point out that tkinter is based on another programming language, called tcl. tkinter is a GUI package in tcl and works with python through a wrapper. So you need to understand a little of both languages here to understand what is going on.

First consider this code here:

import tkinter as tk

def func():
print('func is running')

root = tk.Tk()
b = tk.Button(root, text='exampel', command=func)
b.pack()
root.mainloop()

This is a standard script of creating a window, with a button that can be executed.
If you would add a line of code before root.mainloop() that has the form of this:

print(func)

Output for me

<function func at 0x03D803D8>

this is the information that is stored in this variable. It let you know that this is a object of function with the name func and you will find it at 0x03D803D8.
This information will be interpreted by the wrapper of tkinter and transform it into a string of tcl code. You can proof that by this line:

print(b['command'])

Output

31262160func

This bit of code contains simliar information like python. It contains the information that this is a function and where to find it. I wrote in some depth how Functions & lambda works in python. But what you need to know for this question is just that the syntax () executes the function. After the execution it returns to that point it was called. In python you can return things like strings; integers; objects; etc that will be get in place where the function was called.


So lets consider this code here:

import tkinter as tk

def func():
print('func is running')

def get_func():
return func

root = tk.Tk()
b = tk.Button(root, text='exampel', command=get_func())
b.pack()

root.mainloop()

So what happens here is nonsense, but shows you how it goes. Apart from the code that we considered first we exchanged the function by the optional argument of command with the new function get_func(). Like I explained the function will be executed by the syntax () and with the statement return func we place that fnction object where we called it. So the codes looks more like this, after running:

b = tk.Button(root, text='exampel', command=func)

Add this bit of code here, somewhere over root.mainloop() to get more information of what happens here:

print(get_func)
print(get_func())
print('next')
print(func)
print(func())

Output

<function get_func at 0x02600390> #get_func function
<function func at 0x046303D8> #returned by get_function
next
<function func at 0x046303D8> #func function
func is running
None #returned by func

Let me know if some questions are left.



Update

I still get confused since you called just func and not func() via
command.

The func is stored with the information like I already explained. The parantheses are just like a synonym for run that function. What you generally want to do is to store the function and call it when the Click_Event is happen and not to run that function while the Button is built up. So just imagin that the () is added on the stored function everytime the Click_Event is happen.

I hope you accept this as an answer. Because further more question would include much more information about Class;Eventloop and much more.

Can I call a Python function without brackets, like a shell command. If so, how?

Here's a simple example if you want to parse the string yourself, that's easily extendable.

def mkd(*args):
if len(args) == 1:
print("Making", *args)
else:
print("mdk only takes 1 argument.")

def pwd(*args):
if len(args) == 0:
print("You're here!")
else:
print("pwd doesn't take any arguments.")

def add(*args):
if len(args) == 2:
if args[0].isdigit() and args[1].isdigit():
print("Result:", int(args[0]) + int(args[1]))
else:
print("Can only add two numbers!")
else:
print("add takes exactly 2 arguments.")

def exit(*args):
quit()

functions = {'mkd': mkd, 'pwd': pwd, 'add': add, 'exit': exit} # The available functions.

while True:
command, *arguments = input("> ").strip().split(' ') # Take the user's input and split on spaces.
if command not in functions:
print("Couldn't find command", command)
else:
functions[command](*arguments)

call function without parenthesis in python

Make it a property

class Difference1:
@property
def computeDifference(self):
...

print(c.computeDifference)

However, I would change the name to difference. The idea of a property is that you shouldn't know or care whether the value is computed at that time or is stored as an attribute of the object. See uniform access principle.

call function through variable or without parentheses in python

Python prefers you to be explicit; if you want to re-calculate an expression, you have to call it. But if you really want this to work in the Python interactive interpreter, you'd have to hack it.

You are only echoing a variable, not executing an expression. The variable is not going to change just because you asked the interactive interpreter to echo it.

That is, unless you hook into the echoing mechanism. You can do so with overriding the __repr__ method:

class EvaluatingName(object):
def __init__(self, callable):
self._callable = callable
def __call__(self):
return self._callable()
def __repr__(self):
return repr(self())

ls = EvaluatingName(os.getcwd)

Demo:

>>> import os
>>> class EvaluatingName(object):
... def __init__(self, callable):
... self._callable = callable
... def __call__(self):
... return self._callable()
... def __repr__(self):
... return repr(self())
...
>>> ls = EvaluatingName(os.getcwd)
>>> os.chdir('/')
>>> ls
'/'
>>> os.chdir('/tmp')
>>> ls
'/private/tmp'

This now works because each time an expression produces a value other than None, that value is echoed, and echoing calls repr() on the object.

Note that this will not work outside the interactive interpreter or printing. In other contexts (say, a script) you probably have to convert the object to a string each time. You can't use it as an argument to a function that expects a string, for example.

This will work:

os.path.join(ls(), 'foo.txt')  # produce the value first

but this will not:

os.path.join(ls, 'foo.txt')    # throws an AttributeError.

Python: What is the difference between calling a method with () and without?

If you don't use parenthesis, you aren't calling the function. It's just that simple. sys.exit does absolutely nothing, sys.exit() calls the function.

That being said, sometimes the name of a function without parenthesis will be passed to some other function, or bound to an event. In such a case, parenthesis aren't used because you are telling this other function or event "call this at the appropriate time".

For example, in the tutorial you linked to is this line of code:

self.accept("escape", sys.exit)

This is not calling sys.exit. Instead, it is telling the event system "when you detect the escape key, call this function". At the time this code is called, sys.exit is not called, but rather registered to be called later. When the escape key is pressed, the underlying framework will actually call the function using parenthesis.

So, there is a difference between immediately calling a function (using ()) and registering a function (using the name only, no ()).



Related Topics



Leave a reply



Submit