Pregunta

Este es un ejemplo muy artificial ya que no es fácil de explicar el contexto en el que he terminado la implementación de esta solución. Sin embargo, si alguien puede responder por qué esta peculiaridad particular, sucede, estaría agradecido.

El ejemplo:

class A(dict):  
    def __init__(self):
        self['a'] = 'success'

    def __getitem__(self, name):
        print 'getitem'
        return dict.__getitem__(name)

class B(object):
    def __init__(self):
        self._a = A()
        setattr(self, '__getitem__', self._a.__getitem__) 

b = B()
c = b['a']

Esto da salida:

c = b['a']
TypeError: 'B' object is unsubscriptable

A pesar de que se trata de una extraña manera de hacer esto (claramente la subclasificación sería más lógico), ¿por qué no se encontró el método que se ha establecido explícitamente?

Si hago esto:

dir(b)

Me sale esto:

['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_a']

El mismo problema se produce con otros métodos tales como __iter__. ¿Qué hay en la definición explícita de este método que funciona?

¿Fue útil?

Solución

Cuando se utiliza soportes [] pitón se ve en la clase. Debe establecer el método en la clase.

Aquí está el código adaptado:

class A(dict):  
    def __init__(self):
        self['a'] = 'success'

    def __getitem__(self, name):
        print 'getitem!'
        return dict.__getitem__(self, name)

class B(object):
    def __init__(self):
        self._a = A()
        B.__getitem__ = self._a.__getitem__

b = B()
c = b['a']

Otros consejos

Esto es porque no se puede reemplazar los métodos especiales de clase sobre la marcha.

Yo no era capaz de encontrar una referencia sobre esto, pero es básicamente porque son métodos de clase y no se les permite ser métodos de instancia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top