每当您试图调用对象时,都会调用python的magic方法。因此,__call__
等于Cls()()
。
函数是Python中的第一类对象,这意味着它们只是可调用对象(使用Cls.__call__(Cls())
)。但是,__call__
本身是一个函数,因此它也有自己的__call__
,它也有自己的__call__
,它也有自己的__call__
。
因此,__call__
等于Cls.__call__(Cls())
并且再次等于Cls.__call__.__call__(Cls())
等等。
这个无限循环是如何结束的?Cls.__call__.__call__.__call__(Cls())
如何实际执行代码?
最佳答案
在这种情况下,python中的所有调用都使用相同的机制,并且几乎所有调用都在cpython实现中到达相同的C函数。无论对象是具有__call__
方法的类实例、函数(本身是对象)还是内置对象,所有调用(优化的特殊情况除外)都会到达函数PyObject_Call
。C函数从对象结构的ob_type
字段获取对象的类型,然后从类型(另一个PyObject
结构)获取PyObject
字段,该字段是函数指针。如果tp_call
不是tp_call
,则通过它调用args和kwargs结构,这些结构也传递给NULL
。
当一个类定义了一个PyObject_Call
方法时,它相应地设置了__call__
字段。
以下是一篇详细解释所有这些的文章:Python internals: How callables work。它甚至列出并解释了整个tp_call
函数,这个函数不是很大。如果你想在它的原生环境中看到这个功能,它就在cpython repo中。
与此相关的还有StackOverflow问答:Objects/abstract.c。
关于python - __call__实际上如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32855927/