Python无限__call__属性

时间:2014-06-04 21:52:11

标签: python attributes

我有这个简单的功能:

def f():
    print("heh")

当我在现实中调用f时,我正在调用它的调用方法。但是当我在现实中调用f的调用方法时,我调用f的调用方法的调用方法。等等等等。

当调用f()时,python如何运行,它显然必须停在哪里?

我想知道这是否会变得无穷无尽,事实证明,100 000足以让Python崩溃。

>>> exec('f'+100000*'.__call__'+'()')

========= RESTART ==========

这次崩溃的原因是什么?

1 个答案:

答案 0 :(得分:1)

对象上的“调用”会导致解释器查找调用它的方法。当通过查找__call__方法解决该问题时,将调用该方法,然后发生实际情况。 __call__方法不能仅仅在自身上调用相同的机制。

在函数对象的情况下,我相信有一个内部方法表,首先直接查询是否有一个定义的(C语言)调用处理程序,并且调用它。可能还有__call__属性执行相同的操作,但我认为引擎会首先检查表(其中一些可能已经在Py 3中重新编写)。

函数的'C'语言调用处理程序是对函数对象和参数包的引用。函数对象包含对代码对象的引用,以及对正确的全局名称空间的引用。代码对象包含对预期参数的描述,以及在python堆栈上实际设置调用所需的所有信息。

当你调用一个类的方法时,有一个小的binder对象有自己的调用方法(包含指向'self'和实际方法'的指针)。

我想主要的一点是某些对象有用Python编码的__call__方法,但对于许多类型,解释器在查看对象的内部类型描述符后可以直接转到C代码。另一个例子是调用一个类型对象,比如str,它将调用C语言构造函数。

相关问题