[英]Implementing __getitem__ in new-style classes
我有这个代码:
class A:
def __init__(self):
def method(self, item):
print self, ": Getting item", item
self.__getitem__ = types.MethodType(method, self, self.__class__)
class B(object):
def __init__(self):
def method(self, item):
print self, ": Getting item", item
self.__getitem__ = types.MethodType(method, self, self.__class__)
然后这工作正常:
a = A()
a[0]
但这不会:
b = B()
b[0]
引发类型错误。
我发现新式类在类 __dict__ 中寻找魔术方法,而不是在实例 __dict__ 中。 这是正确的吗? 为什么会这样? 你知道任何解释背后想法的文章吗? 我试过 RTFM,但可能不是正确的,或者没有抓住这个东西......
非常感谢! 保罗
这在 Python 数据模型文档中有记录: 新式类的特殊方法查找:
对于新式类,特殊方法的隐式调用只有在对象的类型上定义时才能保证正确工作,而不是在对象的实例字典中。
和
这种行为背后的基本原理在于许多特殊方法,例如
__hash__()
和__repr__()
由所有对象(包括类型对象)实现。 如果这些方法的隐式查找使用传统的查找过程,则在类型对象本身上调用它们时它们将失败[.]
因此,因为hash(int)
和hash(1)
必须工作,所以在类型上而不是在实例上查找特殊方法。 如果__hash__()
直接在对象上查找, hash(int)
将被转换为int.__hash__()
,这将失败,因为int.__hash__()
是一个未绑定的方法,它期望在实际的int()
实例(例如1
); 所以对于hash(int)
, type.__hash__()
应该改为调用:
>>> hash(1) == int.__hash__(1)
True
>>> hash(int) == type.__hash__(int)
True
>>> int.__hash__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument
这是一个向后不兼容的更改,因此它仅适用于新样式的对象。
特殊方法仅在对象的类是新式类时才查找,与旧式不同。 您正在实例上定义__getitem__
方法,这对新式类没有影响。
默认迭代器在新样式类中不使用__getitem__
。 有关示例,请参见http://grokbase.com/t/python/tutor/085k143q1r/new-style-classes-getitem-and-iteration 。似乎__getitem__
的行为随着 python 2.2 和新的类样式而改变
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.