【问题标题】:Are functions objects in Python?Python中的函数是对象吗?
【发布时间】:2014-10-07 04:07:07
【问题描述】:

我总是在 Python 中听到这种说法(在传递函数时,例如装饰器等主题),但从未真正看到过对此的详细说明。

例如,是否可以创建一个类c,它只有一个抽象方法,该方法通过一组开括号和闭括号调用。

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

所以你可以拥有

c(whatever parameters are required)

我的理解可能有点离题,我只是好奇人们的意思。

【问题讨论】:

  • c(...) 通过调用__init__ 创建一个c 类型的新对象。一旦你有了一个新对象,比如说x,调用x()调用c.__call__
  • hmm,但是当你编写一个函数时,你不需要创建它的实例来使用它。不知道我错过了什么。
  • 您不需要创建函数的实例。 c 是一个
  • @user3684792:您也不必使用int()str() 类型来创建整数;您也可以使用语法、字符串文字或 int 文字来创建它们。 1 创建一个 int() 类型的对象。与函数相同。
  • @hlt:实际上,每当您使用def 语句或lambda 表达式时,Python 都会创建函数类型的实例。它只是透明的并由语法处理。

标签: python function class methods


【解决方案1】:

您正在寻找__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() 来获得。

我还传入了我的解释器的全局命名空间,以及一个名字;后者是可选参数;否则名称取自代码对象。

【讨论】:

  • 好的,这确实很有趣。所以还需要先初始化吗?有没有办法像使用函数一样获取 Callable('Hello')。我不确定函数的幕后发生了什么
  • @user3684792:解释器会为你创建函数实例,总的来说你不需要自己做。我已经说明了如何创建函数类型的新实例;它需要一个代码对象。代码对象包含 Python 字节码,您现在真正进入了 Python 实现;如果您想了解这一切如何结合在一起的绝对细节,请阅读Python datamodel document
  • aha - 所以 def 语句有效地初始化了函数对象?
  • 我会去看看那个文档,你。你的技能很强大
  • @user3684792:完全正确。就像其他语法创建列表对象、字典、字符串或整数一样。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2017-06-09
    • 2014-09-02
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2020-02-20
    • 1970-01-01
    相关资源
    最近更新 更多