【问题标题】:Purpose of calling function without brackets python调用不带括号的函数python的目的
【发布时间】:2014-03-14 04:51:06
【问题描述】:

考虑以下几点:

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

【问题讨论】:

  • 以防万一你来到这里是因为你真的想在没有括号的情况下调用一个函数,注意有时可以通过 hacky decators。例如>>> f = lambda *args: print('hi') >>> @f ... class _: pass ... hi
  • @Chris_Rands 你什么时候需要这样做?

标签: python python-3.x


【解决方案1】:

如前所述,函数和方法是一流的对象。您调用它们,方法是在末尾添加一些括号(方括号)。但看起来你想要更多的动力来解释为什么 python 甚至让我们这样做。我们为什么要关心函数是否是一流的?

有时您不想调用它们,而是想传递对可调用对象本身的引用。

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

如果你在上面加上括号,它会在你的主线程中运行你的my_long_running_function;几乎没有你想要的!您想为 Process 提供对您的可调用对象的引用,以使其在新进程中自行运行。

有时您只想指定可调用对象并让其他内容...

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

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

(在这种情况下为map)填写其参数。

也许您只是想将一堆可调用对象放入某个集合中,然后以动态方式获取您想要的对象。

from operator import *

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

以上是将运算符的字符串表示映射到其实际操作的一种方法。

【讨论】:

  • 所以在这种情况下,如果我在代码中看到assert do_something,这意味着什么?总之,assert 函数会实现什么?
【解决方案2】:

Python 中的函数和方法本身也是对象。因此,您可以像比较任何其他对象一样比较它们。

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

通常,您当然不会将方法彼此或其他任何方法进行比较,因为它并不是非常有用。一个有用的地方是当你想将一个函数传递给另一个函数时。

【讨论】:

  • 为了简要扩展 Mark 的评论,当您输入 a.get_value 末尾没有括号时,您实际上并没有调用该方法。您只是在引用与该方法关联的对象。
  • 举一些例子说明如何使用这个\为什么这是可取的并获得+1
【解决方案3】:
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 :)

【讨论】:

    【解决方案4】:
    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
    

    【讨论】:

      【解决方案5】:

      几位评论员想要一个有用的例子。一种应用是线程化。我们需要在不使用括号的情况下将目标传递给线程。否则目标是在主线程中创建的,这是我们试图避免的。

      例子:

      在 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。

      【讨论】:

        【解决方案6】:

        不带括号的函数和带括号的函数之间的区别在于,使用括号时您将获得该函数的输出,而当您使用不带括号的函数时,您将创建该函数的副本。 例如

        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')
        

        这里我们将函数 outerFunction 复制到 x,然后将 y 复制到 x。

        【讨论】:

          猜你喜欢
          • 2016-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-01
          • 2017-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多