Até agora, isso está me deixando confuso. Como entender o código abaixo para obter o resultado? Alguém pode explicar abaixo duas partes da saída como o fluxo realmente acontece? A primeira parte mostra a saída como "C" e a segunda parte como "A".
class A:
def fun1(self):
print("A")
class B(A):
def fun1(self):
print('B')
class C(A):
def fun1(self):
print("C")
class D(B, C):
def fun1(self):
super(B, self).fun1()
obj = D()
obj.fun1() **# How output will be 'C' in this case ?**
output : C
class A:
def fun1(self):
print("A")
class B(A):
def fun1(self):
print("B")
class C(A):
def fun1(self):
print("C")
class D(B, C):
def fun1(self):
super(C, self).fun1()
obj = D()
obj.fun1() **# How output will be 'A' in this case ?**
output : A
Python usa linearização C3 para calcular uma Ordem de Resolução de Método (MRO) determinística. Este é um algoritmo bem documentado, e parece que não é isso que você está realmente perguntando.
Parece que você está perguntando o que os argumentos
super
significam e comosuper()
funcionam, porque entender isso explica por que os dois exemplos que você postou dão o resultado que dão.A chamada
super()
retorna um objeto super proxy. Sempre que você acessa um método nele, o MRO determina qual método você obtém.Sem argumentos, o proxy resultante começa a procurar na classe da instância atual ao procurar algo para acessar no objeto atual. Se você criá-lo com argumentos, ele espera dois argumentos: a classe pai no MRO, após a qual deve começar a procurar, e o objeto ao qual se aplica especificamente.
Então, em seus exemplos:
Aqui a saída é
C
porquefun1
pode ser encontradasuper(B, self)
emC
. Ela não a encontra emB
porque você disse explicitamentesuper
para começar a procurar noB
MRO, e o MRO paraobj
aqui éD, B, C, A, object
.Adicionando o segundo exemplo ao mesmo código:
A saída será
A
, porque o MROobj
éE, B, C, A, object
e você está dizendo para ele começar a cuidar deC
.Se você está se perguntando por que o MRO existe,
D/E, B, C, A, object
você pode dar uma olhada no artigo da Wikipédia sobre Linearização C3 .Se você só quer saber como determinar qual é o MRO para um objeto específico, você pode simplesmente fazer o Python lhe dizer:
Saída (para o primeiro exemplo):
(Supondo que suas definições de classe estejam no módulo principal.)