Python中的函数对象是什么?

时间:2014-08-13 17:12:00

标签: python function class methods

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

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

i.e class c:
       @abstractmethod
       def method_to_be_called_by():
        ... 

所以你可以拥有

c(whatever parameters are required)

我的理解可能与我的理解不符,我只是对这个人的意思感到好奇。

2 个答案:

答案 0 :(得分:30)

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

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

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

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

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

    def __call__(self, greeting):
        return '{}, {}!'.format(greeting, self.name)

演示:

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

当您使用def statement使用lambda expression时,Python会为您创建 功能对象:

>>> def foo(): pass
... 
>>> foo
<function foo at 0x106aafd70>
>>> lambda: None
<function <lambda> at 0x106d90668>

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

listobject = [1, 'two']

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

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

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

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

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

答案 1 :(得分:5)

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

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

对于另一种方法,如果对象具有magic __call__() method,则它们是函数。