Pergunta

Este é um exemplo muito artificial, uma vez que não é fácil de explicar o contexto em que eu acabei implementação desta solução. No entanto, se alguém pode responder por essa peculiaridade especial acontece, eu ficaria grato.

O exemplo:

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']

Esta saídas:

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

Mesmo que seja uma forma bizarra de fazer isso (claramente subclasse seria mais lógico), por que não encontrar o método que eu definir explicitamente?

Se eu fizer isso:

dir(b)

fico com esta:

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

O mesmo problema ocorre com outros métodos, como __iter__. O que é sobre explicitamente definir este método que funciona?

Foi útil?

Solução

Quando você usa colchetes [] aparência python na classe. Você deve definir o método na classe.

Aqui está seu 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']

Outras dicas

Isso é porque você não pode substituir métodos de classe especial na mosca.

Eu não era capaz de encontrar uma referência sobre isso, mas é basicamente porque são métodos de classe e não estão autorizados a ser métodos de instância.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top