gpt4 book ai didi

python - 函数、可调用对象以及如何在 Python 中创建它们

转载 作者:IT老高 更新时间:2023-10-28 21:12:54 31 4
gpt4 key购买 nike

我想知道函数和可调用对象之间更复杂的区别。例如,如果你这样做:

def foo1():
return 2 + 4

class foo2:
def __call__():
return 2 + 4

import sys
sys.getsizeof(foo1) # returns 136
sys.getsizeof(foo2) # returns 1016

函数和可调用对象之间显然有很大的区别。但是,我找不到很多关于幕后发生的事情的文档。我知道函数是一流的对象,但我也知道类比常规函数要多得多。类 foo2 是使用元类 type() 创建的。

那么我的问题是:

  1. 当你创建一个函数 def foo1(): 时,它与用元类定义类的过程?是否有 type() 的版本,但对于函数,是元函数?
  2. 假设有人想编写自己的元函数(这背后的真正原因),是只使用装饰器更好,还是使用生成可调用类的元类更好?两者都会提供哪些优势(使可调用类看起来很笨重的元类)?
  3. 拥有一个可调用对象的唯一目的是拥有一个可以在其中存储信息的函数吗?

最佳答案

函数也是可调用对象:

>>> foo1.__call__
<method-wrapper '__call__' of function object at 0x105bafd90>
>>> callable(foo1)
True

但是一个类需要跟踪更多信息;在这里你给它一个 __call__ 方法并不重要。 任何类都比函数大:

>>> import sys
>>> def foo1():
... return 2 + 4
...
>>> class foo3:
... pass
...
>>> sys.getsizeof(foo1)
136
>>> sys.getsizeof(foo3)
1056

函数对象是一种不同的对象类型:

>>> type(foo1)
<class 'function'>

并且相当紧凑,因为肉实际上不在函数对象中,而是在函数对象引用的其他对象中:

>>> sys.getsizeof(foo1.__code__)
144
>>> sys.getsizeof(foo1.__dict__)
240

真的就是这样;不同类型的对象具有不同的大小,因为它们跟踪不同的事物或使用组合将内容存储在其他对象中。

如果您愿意,可以使用 type(foo1) 返回值(或 types.FunctionType,这是同一个对象)来生成新的函数对象:

>>> import types
>>> types.FunctionType(foo1.__code__, globals(), 'somename')
<function foo1 at 0x105fbc510>

这基本上是解释器在执行 def function(..): ... 语句时所做的事情。

使用 __call__ 使自定义类在对您的 API 有意义时可调用。 enum.Enum() class is callable ,例如,特别是因为使用调用语法为您提供了与订阅不同的语法,订阅用于其他目的。还有一个 xmlrpc.client.ServerProxy() object生成作为 _Method 实例的方法对象,因为它们代理远程调用,而不是本地函数。

关于python - 函数、可调用对象以及如何在 Python 中创建它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40182637/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com