请考虑以下事项:
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();
此代码返回
>>>
False
False
True
False
鉴于get_value是一个函数,我希望执行停止并返回错误,但事实并非如此。有人可以解释为什么python解释器允许这种语法而不是引发属性错误,这在我的情况下会节省我宝贵的时间。
答案 0 :(得分:22)
如上所述,函数和方法是一流的对象。你通过在末尾抛出一些括号(括号)来调用它们。但看起来你想要更多的动机,为什么python甚至让我们这样做。如果功能是一流的,我们为什么要关心呢?
有时你不想调用它们,你想要传递对callable本身的引用。
from multiprocessing import Process
t = Process(target=my_long_running_function)
如果你把括号放在上面,它会在主线程中运行你的my_long_running_function
;几乎没有你想要的!你想给Process
一个对你的callable的引用,它将在一个新进程中自行运行。
有时你只想指定可调用的东西并让别的东西......
def do_something(s):
return s[::-1].upper()
map(do_something,['hey','what up','yo'])
Out[3]: ['YEH', 'PU TAHW', 'OY']
(在这种情况下为map
)填写其参数。
也许你只想将一堆callables放入某个集合中,然后以动态的方式获取你想要的那个。
from operator import *
str_ops = {'<':lt,'>':gt,'==':eq} # etc
op = str_ops.get(my_operator)
if op:
result = op(lhs,rhs)
以上是将运算符的字符串表示映射到实际操作的一种方法。
答案 1 :(得分:17)
Python中的函数和方法本身也是对象。因此,您可以像对待任何其他对象一样比较它们。
>>> type(a.get_value)
<type 'instancemethod'>
>>> type(a.get_value())
<type 'int'>
当然,你当然不会将方法与其他方法或其他方法进行比较,因为它并不是非常有用。一个有用的地方是你想把一个函数传递给另一个函数。
答案 2 :(得分:4)
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)调用a.get_value()的返回值是否等于方法b.get_value?
2)a.get_value()是否与b.get_value()返回相同?
3)方法引用a.get_value是否等于方法引用b.get_value?
这是完全有效的Python:)
答案 3 :(得分:2)
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
答案 4 :(得分:0)
一些评论员想要一个有用的例子。一个应用程序是线程。我们需要将目标传递给线程而不使用括号。否则,目标是在主线程中创建的,这是我们试图避免的。
示例:
在test1.py中,我在不使用括号的情况下调用ThreadTest。 test_thread在线程中启动,允许test1.py继续运行。
在test2.py中,我传递ThreadTest()作为目标。在这种情况下,线程不允许test2.py继续运行。
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')
从test1.py输出:
thread_test started
not blocked
test_thread
test_thread
test_thread
从test2.py输出:
thread_test started
test_thread
test_thread
test_thread
我在Linux Mint上使用python3.5。
答案 5 :(得分:0)
不带括号的函数和带括号的函数之间的区别在于,使用括号时,您将获得该函数的输出;而当使用不带括号的函数时,则将创建该函数的副本。 例如
def outerFunction(text):
text = text
def innerFunction():
print(text)
return innerFunction()
if __name__ == '__main__':
outerFunction('Hey!')
x = outerFunction
y = x
x('Hey i am busy can you call me later')
y('this is not a function')
在这里,我们将功能externalFunction复制到x,然后将y复制到x。