Python中的函数对象是什么?

use*_*792 22 python methods class function

我总是在Python中听到这个声明(对于诸如装饰器之类的主题,当你传递函数时等)但是从未真正看到过这方面的细节.

例如,是否可以创建一个c只有一个抽象方法的类,该方法使用一组打开和关闭的括号进行调用.

i.e class c:
       @abstractmethod
       def method_to_be_called_by():
        ... 
Run Code Online (Sandbox Code Playgroud)

所以你可以拥有

c(whatever parameters are required)
Run Code Online (Sandbox Code Playgroud)

凭借我的理解,我可能会脱离标记,我只是对这个人的意思感到好奇.

Mar*_*ers 30

您正在寻找该__call__方法.函数对象具有以下方法:

>>> def foo(): pass
... 
>>> foo.__call__
<method-wrapper '__call__' of function object at 0x106aafd70>
Run Code Online (Sandbox Code Playgroud)

并不是Python解释器循环在遇到Python函数对象时实际上使用了该方法; 在大多数情况下,实现中的优化直接跳转到包含的字节码.

但您可以在自己的自定义类中使用它:

class Callable(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, greeting):
        return '{}, {}!'.format(greeting, self.name)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> class Callable(object):
...     def __init__(self, name):
...         self.name = name
...     def __call__(self, greeting):
...         return '{}, {}!'.format(greeting, self.name)
... 
>>> Callable('World')('Hello')
'Hello, World!'
Run Code Online (Sandbox Code Playgroud)

Python 在您使用语句时为您创建函数对象,或者您使用表达式:deflambda

>>> def foo(): pass
... 
>>> foo
<function foo at 0x106aafd70>
>>> lambda: None
<function <lambda> at 0x106d90668>
Run Code Online (Sandbox Code Playgroud)

您可以将其与使用文字语法创建字符串或整数或列表进行比较:

listobject = [1, 'two']
Run Code Online (Sandbox Code Playgroud)

上面创建了3个对象而没有调用类型,Python根据所使用的语法为您完成了所有这些操作.这同样适用于功能.

自己创造一个可能会更复杂; 您需要拥有一个代码对象并引用一个全局命名空间,至少:

>>> function_type = type(lambda: None)
>>> function_type
<type 'function'>
>>> function_type(foo.__code__, globals(), 'bar')
<function bar at 0x106d906e0>
Run Code Online (Sandbox Code Playgroud)

在这里,我通过重用function类型创建了一个函数对象,从foo函数中获取代码对象; 函数类型不是内置名称,但类型确实存在,可以通过调用type()现有函数实例来获取.

我还传入了我的解释器的全局命名空间和一个名字; 后者是一个可选的论点; 否则从代码对象中获取名称.

  • @user3684792:完全正确。就像其他语法创建列表对象、字典、字符串或整数一样。 (2认同)

sha*_*apr 5

一个简单的方法是在Python解释器中创建一个函数def bar(x): return x + 1,然后用它dir(bar)来查看各种魔术属性,包括__class__.

是的,python函数是完整的对象.

对于另一种方法,如果对象具有魔术__call__()方法,则它们是函数.