No livro Python in a Nutshell (2ª edição), há um exemplo que usa
classes de estilo antigo para demonstrar como os métodos são resolvidos na ordem de resolução clássica e
como é diferente com a nova ordem.
Tentei o mesmo exemplo reescrevendo o exemplo no novo estilo, mas o resultado não é diferente do que foi obtido com as classes do estilo antigo. A versão python que estou usando para executar o exemplo é 2.5.2. Abaixo está o exemplo:
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
A chamada é instance.amethod()
impressa Base1
, mas de acordo com meu entendimento do MRO com novo estilo de classes, a saída deveria ter sido Base3
. A chamada é Derived.__mro__
impressa:
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
Não tenho certeza se meu entendimento de MRO com novas classes de estilo está incorreto ou se estou cometendo um erro bobo que não sou capaz de detectar. Por favor, me ajude a entender melhor o MRO.
fonte
A ordem de resolução do método do Python é na verdade mais complexa do que apenas entender o padrão do diamante. Para realmente entendê-lo, dê uma olhada na linearização C3 . Descobri que realmente ajuda usar instruções de impressão ao estender métodos para rastrear o pedido. Por exemplo, qual você acha que seria a saída desse padrão? (Nota: o 'X' é suposto ser duas arestas cruzadas, não um nó e ^ significa métodos que chamam super ())
Você conseguiu ABDCEFG?
Depois de muitas tentativas e erros, cheguei a uma interpretação informal da teoria dos grafos da linearização C3 da seguinte maneira: (Alguém, por favor, me avise se estiver errado.)
Considere este exemplo:
fonte
super
tem argumentos necessários.O resultado obtido está correto. Tente alterar a classe base de
Base3
paraBase1
e compare com a mesma hierarquia para classes clássicas:Agora ele produz:
Leia esta explicação para mais informações.
fonte
Você está vendo esse comportamento porque a resolução do método prioriza a profundidade, não a amplitude. A herança de Dervied parece
assim
instance.amethod()
amethod
, por isso é chamado.Isso se reflete em
Derived.__mro__
. Simplesmente repitaDerived.__mro__
e pare quando encontrar o método que está sendo procurado.fonte