Python brackets call function assignment

Consider the following:

class objectTest(): def __init__(self,a): self.value = a def get_value(self): return self.value class execute(): def __init__(self): a = objectTest(1) b = objectTest(1) print(a == b) print(a.get_value() == b.get_value) print(a.get_value() == b.get_value()) print(a.get_value == b.get_value) if __name__ == '__main__': execute = execute(); 

This code returns

 >>> False False True False 

Given that get_value is a function, I would expect execution to stop and return an error, but that is not the case. Can someone explain why the python interpreter allows such a syntax instead of raising an attribute error, which in my case would save me valuable time.

+14
python
source share
6 answers

As already mentioned, functions and methods are first-class objects. You call them by casting brackets (parentheses) at the end. But it looks like you need another motivation for why python even allows us to do this. Why should we be wondering if features are first-class or not?

Sometimes you donโ€™t want to call them, you want to pass a link to the called yourself.

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

If you put the brackets after the above, it runs your my_long_running_function in your main thread; hardly what you wanted! You would like to give Process link to your called code so that it starts in a new process.

Sometimes you just want to specify the callee and allow 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 your arguments.

Maybe you just want to drop a bunch of calls into some collection and pull out the one you want dynamically.

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

The above method is to match the string representations of the operators with their actual action.

+24
source share

Functions and methods in Python are also objects. This way you can compare them just like any other object.

 >>> type(a.get_value) <type 'instancemethod'> >>> type(a.get_value()) <type 'int'> 

Usually, of course, you will not compare methods with each other or anything else, because it is not very useful. In one place, this is useful when you want to pass a function to another function.

+17
source share
 print(a.get_value() == b.get_value) # 1 print(a.get_value() == b.get_value()) # 2 print(a.get_value == b.get_value) # 3 

1) Is the return value of the a.get_value () call equal to the b.get_value method?

2) Does a.get_value () return the same as b.get_value ()?

3) Is the reference method a.get_value equal to the reference method b.get_value?

This is perfectly valid Python :)

+4
source share
 def mul(a, b): return a * b def add(a, b): return a + b def do(op, a, b): return op(a, b) do(add, 2, 3) # return 5 
+2
source share

Several commentators want an example of where this is useful. One application is in a thread. We need to pass the target to the stream without using parentheses. Otherwise, the goal is created in the main thread, which we are trying to avoid.

Example:

In test1.py, I call ThreadTest without using parentheses. test_thread runs in the thread and allows test1.py to continue.

In test2.py, I pass ThreadTest () as the target. In this case, the thread does not allow test2.py to continue.

test1.py

 import threading from thread_test import ThreadTest thread = threading.Thread(target=ThreadTest) thread.start() print('not blocked') 

test2.py

 import threading from thread_test import ThreadTest thread = threading.Thread(target=ThreadTest()) thread.start() print('not blocked') 

test_thread.py

 from time import sleep class ThreadTest(): def __init__(self): print('thread_test started') while True: sleep(1) print('test_thread') 

output from test1.py:

 thread_test started not blocked test_thread test_thread test_thread 

output from test2.py:

 thread_test started test_thread test_thread test_thread 

I am using python3.5 on Linux Mint.

0
source share

The difference between a function without brackets and brackets is that when you use brackets, you get the output of this function, and when you use a function without brackets, you will create a copy of this function. eg

 def outerFunction(text): text = text def innerFunction(): print(text) return innerFunction() if __name__ == '__main__': outerFunction('Hey!') x = outerFunction y = xx('Hey i am busy can you call me later') y('this is not a function') 

here we copy the externalFunction function to x, and then copy y to x.

0
source share

All Articles