假设我想在Python类中覆盖像__int__
这样的函数,这样我就可以这样做。
class A(object):
def __init__(self):
self.__int__ = lambda: 1
a = A()
print int(a)
我希望它会输出“1”而不是产生此错误消息
TypeError:int()参数必须是字符串或数字,而不是'A'
当__int__
成为类中内置的方法时,它按预期工作。为什么? (任何双下划线函数都存在此问题)
答案 0 :(得分:3)
这似乎是__
魔术方法中的一点魔力。与其他方法不同,当隐式调用时,它们不会在类实例上查找。
有充分证据表明他们没有使用__getattribute__
魔术方法解决(如果他们这样做,那将是一个很好的悖论,因为__getattribute__
必须调用自己来解析自己的名字)。但不检查实例让我感到惊讶。
这里有一点讨论,在标题“特殊方法查找”下: http://segfaulthunter.github.io/articles/biggestsurprise/
对于新式类的实例,所有特殊方法查找都是在类结构中完成的。因此,更改实例的
__str__
属性不会影响str()的结果。但是,明确地从实例获取属性会为您提供实例中的方法。
我很想知道是否有其他人可以提供更详细的解释。
答案 1 :(得分: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
VS
class A(object):
def __init__(self):
self._int = 1
def __int__(self):
return self._int
现在有一个非常大的区别:第二种变体有效,第一种不起作用。这是因为总是在类上查找特殊方法,而不是实例。这是设计的。
因此,不要试图变得聪明,只要写出清晰可读的内容。在Python中往往效果最好。 ; - )