court circuiter __getitem__ par attribut
Bonjour,
Lorsque l'on assigne un attribut ayant le même nom qu'une méthode, celui ci prends la priorité sur cette dernière. Est ce normal si cela ne fonctionne pas pour l'attribut __getitem__, accédé avec la syntaxe d[] ? (Je suis en Py25)
Merci d'avance
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
class A(dict):
def __init__(self):
dict.__init__(self)
def __getitem__(self, k):
print "A.get ",k
return dict.__getitem__(self, k)
class D(A):
def __init__(self):
A.__init__(self)
self._inner= dict()
"Shortcuts __getattr__ to self._inner"
self.__getattr__= self._inner.__getitem__
if __name__ == '__main__':
d=D()
d._inner[0]= 1
d[0]= 1
print "d.__getattr__(0)"
d.__getattr__(0) # does not call A.__getitem__, as expected
print "d[0]"
d[0] # this CALLS A.__getitem__, UNEXPECTED ! |
et un cas qui fait planter
Si on dérive d'object et de la classe qui particularise la méthode dans le constructeur, on obtient une jolie
Citation:
TypeError: 'xD' object does not support item assignment
J'en conclus que type() se comporte très différemment quand on dérive d'object, mais ça ma laisse perplexe quand même. Pourquoi Python a-t'il besoin de faire type(x).__getitem__(x, i) , plutôt que getattr(x,'__getitem__')(i) ???
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
class A(dict):
def __init__(self): dict.__init__(self)
def __getitem__(self, k):
print "A.get ",k
return dict.__getitem__(self, k)
class D(A):
def __init__(self):
A.__init__(self)
self._inner= dict()
"Shortcuts __getitem__ to self._inner"
self.__getitem__= self._inner.__getitem__
self.__setitem__= self._inner.__setitem__
class DD:
def __init__(self):
self._inner= dict()
self.__getitem__= self._inner.__getitem__
self.__setitem__= self._inner.__setitem__
class xD(DD,object):
def __init__(self): DD.__init__(self)
def test(d):
d._inner[0]= 1
d[0]= 1
print "d[0]"
d[0]
print "d.__getitem__(0)"
d.__getitem__(0)
if __name__ == '__main__':
# d=D()
# print "D---"*20
# test(d)
# d=DD()
# print "DD--"*20
# test(d)
d=xD()
print "xD--"*20
test(d) |