繁体   English   中英

在新式类中实现 __getitem__

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM