Parentheses denote that you actually want to call the method, rather than mention it for later use. On a line of its own, the latter doesn't appear to make sense, but in larger expressions, it allows delaying the function call:
# access the "date" method, but don't call it yet
fn = datetime.datetime.now().date
... do other things ...
# *now* call date()
print(fn())
The callable object stored in fn
is a bound method, and it refers to a concrete object. In Python there is no fundamental difference between a method call and a function call: accessing a method by name creates a bound method object, which is then called as any other function. As far as Python is concerned, omitting the parentheses simply means that you are not (yet) interested in calling it.
This is useful when you have a function that accepts a callable. For example, imagine calling into an event processor that allows you to provide a custom callable for processing events. Normally the events are dispatched through GUI, but you want to (temporarily) want to collect the events in a list you've just created. This would be a use case for a bound method:
# library function that we cannot change
def do_processing(dispatchfn):
for event in something_that_generates_events():
... internal bookkeeping
# dispatch the event
dispatchfn(event)
# our code to log the events
log = []
do_processing(log.append)
# ... inspect the events list, e.g.:
for event in log:
print event
In this case, an alternative to using a bound method would be to use a lambda
:
do_processing(lambda event: log.append(event))
But a lambda
has subtly different semantics and performance. Using a bound method can actually improve performance in very tight loops. A popular optimization in Python is to transform a tight loop:
todo = deque()
while todo:
next_item = todo.popleft()
...
into:
todo = deque()
todo_popleft = todo.popleft
while todo:
next_item = todo_popleft()
...
If the while
loop does really little, this transformation can actually improve performance because it eliminates the cost of one dict lookup and of creation of the bound method. This is not something that should be done routinely, but it is a recognized usage of uncalled bound methods.