4

假设我想重写一个__int__Python 类中的函数,这样我就可以做这样的事情。

class A(object):
    def __init__(self):
        self.__int__ = lambda: 1

a = A()
print int(a)

我希望它会在此处输出“1”而不是产生此错误消息

TypeError:int() 参数必须是字符串或数字,而不是“A”

相反,当__int__它成为类中内置的方法时,它会按预期工作。为什么?(这个问题也存在于任何双下划线函数中)

4

2 回答 2

3

这似乎是__魔法方法中的一种魔法。与其他方法不同,它们在隐式调用时不会在类实例上进行查找。

有据可查的是,他们不能用__getattribute__魔法方法解决(如果他们这样做了,那将是一个很好的悖论,因为__getattribute__必须调用自己来解决自己的名字)。但不检查实例让我感到惊讶。

在这里讨论了一下,在标题“特殊方法查找”下: http ://segfaulthunter.github.io/articles/biggestsurprise/

对于新式类的实例,所有隐式完成的特殊方法查找都在类结构中完成。因此更改实例的__str__属性不会影响 str() 的结果。尽管如此,从实例中显式获取属性会为您提供实例中的方法。

我很想知道是否有其他人可以提供更详细的解释。

于 2013-11-03T06:32:01.027 回答
1

如果我们暂时忽略您询问特殊方法,那么您的代码将如下所示:

class A(object):
    def __init__(self):
        self.a_fun = lambda: 1

写得更清楚是这样的:

class A(object):
    def __init__(self):
        self._int = 1

    def a_fun(self):
        return self._int

生成的代码并不完全相同,但足够接近以至于不会产生太大影响。唯一的区别是必须将_int名称作为属性进行查找。

但是如果我们现在把它改回一个特殊的方法,它看起来像这样:

class A(object):
    def __init__(self):
        self.__int__ = lambda: 1

与:

class A(object):
    def __init__(self):
        self._int = 1

    def __int__(self):
        return self._int

现在有一个很大的不同:第二个变体有效,第一个无效。这是因为总是在类而不是实例上查找特殊方法。这是设计使然。

因此,与其试图变得聪明,不如写出清晰易读的东西。在 Python 中往往效果最好。;-)

于 2013-11-03T16:06:07.490 回答