调用函数的目的没有括号python

时间:2014-02-14 17:37:38

标签: python python-3.x

请考虑以下事项:

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解释器允许这种语法而不是引发属性错误,这在我的情况下会节省我宝贵的时间。

6 个答案:

答案 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。