Implementing __getitem__ In New-style Classes
Solution 1:
This is documented in the Python datamodel documentation: Special method lookup for new-style classes:
For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.
and
The rationale behind this behaviour lies with a number of special methods such as
__hash__()
and__repr__()
that are implemented by all objects, including type objects. If the implicit lookup of these methods used the conventional lookup process, they would fail when invoked on the type object itself[.]
So, because both hash(int)
andhash(1)
must work, special methods are looked up on the type instead of on the instance. If __hash__()
was looked up straight on the object, hash(int)
would be translated to int.__hash__()
, and that would fail, because int.__hash__()
is an unbound method and it expects to be called on an actual instance of int()
(e.g. 1
); so for hash(int)
, type.__hash__()
should called instead:
>>> 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
This is a backwards-incompatible change, so it only applies to new-style objects.
Solution 2:
Special methods are only looked up against an object's class if its a new-style class, unlike old-style ones. You're defining the __getitem__
method on the instance, which has no effect with the new-style class.
Solution 3:
The default iterators do not use__getitem__
in new style classes. See http://grokbase.com/t/python/tutor/085k143q1r/new-style-classes-getitem-and-iteration for an example.It seems like the behaviour of __getitem__
has changed with python 2.2 and the new style of classes
Post a Comment for "Implementing __getitem__ In New-style Classes"