gpt4 book ai didi

python - Python 如何告诉 “this is called as a function” ?

转载 作者:行者123 更新时间:2023-12-04 19:05:35 25 4
gpt4 key购买 nike

通过定义 __call__ 应该是一个可调用的对象。 .一个类应该是一个对象……或者至少有一些异常(exception)。这个异常(exception)是我没有正式澄清的,因此这个问题发布在这里。

A成为一个简单的类:

class A(object):

def call(*args):
return "In `call`"

def __call__(*args):
return "In `__call__`"

第一个函数特意命名为“调用”,以明确目的是与其他函数进行比较。

让我们实例化它并忘记它所暗示的表达式:
a = A() # Think of it as `a = magic` and forget about `A()`

现在什么是值得的:
print(A.call())
print(a.call())
print(A())
print(a())

导致:
>>> In `call`
>>> In `call`
>>> <__main__.A object at 0xNNNNNNNN>
>>> In `__call__`

输出(第三条语句没有运行 __call__)并不令人惊讶,但是当我认为每个地方都说“Python 类是对象”时……

这更明确,但是运行 __call__
print(A.__call__())
print(a.__call__())

>>> “In `__call__`”
>>> “In `__call__`”

所有这一切只是为了展示如何最终 A()可能看起来很奇怪。

Python 规则中有异常(exception),但 the documentation about “object.call不多说 __call__ ……不止于此:

3.3.5. Emulating callable objects

object.__call__(self[, args...])

Called when the instance is “called” as a function; […]



但是 Python 如何告诉“它作为函数调用”并尊重与否 object.__call__规则?

这可能是类型的问题,但即使类型也有 object作为它的基类。

我在哪里可以了解更多(和正式)关于它的信息?

顺便说一句,Python2 和 Python3 之间有什么区别吗?

----- %< ----- 编辑 ----- >% -----

一个答案和一个评论后的结论和其他实验

更新 #1

在@Veedrac 的回答和@chepner 的评论之后,我来到了另一个测试,它完成了两者的评论:
class M(type):

def __call__(*args):
return "In `M.__call__`"

class A(object, metaclass=M):

def call(*args):
return "In `call`"

def __call__(*args):
return "In `A.__call__`"

print(A())

结果是:
>>> In `M.__call__`

所以这似乎是驱动“调用”操作的元类。如果我理解正确,元类不仅与类有关,而且与类实例有关。

更新 #2

另一个相关测试,它表明这不是重要的对象属性,而是对象类型的属性:
class A(object):

def __call__(*args):
return "In `A.__call__`"

def call2(*args):
return "In `call2`"


a = A()

print(a())

正如预期的那样,它打印:
>>> In `A.__call__`

现在这个:
a.__call__ = call2

print(a())

它打印:
>>> In `A.__call__`

分配属性之前的 a 相同。它不打印 In call2 ,还是 In A.__call__ .重要的是要注意并解释为什么是 __call__被调用的元类(记住元类是类对象的类型)。 __call__用来作为函数调用的,不是来自对象,而是来自它的类型。

最佳答案

x(*args, **kwargs)type(x).__call__(x, *args, **kwargs) 相同.

所以你有了

>>> type(A).__call__(A)
<__main__.A object at 0x7f4d88245b50>

这一切都说得通。

chepner 在评论中指出 type(A) == type .这有点奇怪,因为 type(A)(A)只给 type再次!但请记住,我们使用的是 type(A).__call__(A)这是 不一样 .

所以这解析为 type.__call__(A) .这是类的构造函数,它构建数据结构并完成所有构造魔法。

大多数 dunder(双下划线)方法也是如此,例如 __eq__ .在这些情况下,这部分是一种优化。

关于python - Python 如何告诉 “this is called as a function” ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25771421/

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