Ao criar uma hierarquia de objetos simples em Python, eu gostaria de poder invocar métodos da classe pai de uma classe derivada. No Perl e Java, há uma palavra-chave para this ( super
). No Perl, eu devo fazer isso:
package Foo;
sub frotz {
return "Bamf";
}
package Bar;
@ISA = qw(Foo);
sub frotz {
my $str = SUPER::frotz();
return uc($str);
}
Em Python, parece que eu tenho que nomear explicitamente a classe pai do filho. No exemplo acima, eu teria que fazer algo parecido Foo::frotz()
.
Isso não parece certo, pois esse comportamento dificulta a criação de hierarquias profundas. Se as crianças precisarem saber que classe definiu um método herdado, todos os tipos de problemas de informação serão criados.
Isso é uma limitação real em python, uma lacuna no meu entendimento ou em ambos?
python
inheritance
class
object
jjohn
fonte
fonte
Respostas:
Sim, mas apenas com classes de novo estilo . Use a
super()
função:Para python <3, use:
fonte
super(Foo, self)
é correta para o Python 2.x? No Python 3.x, osuper()
preferido é correto?O Python também tem super :
super(type[, object-or-type])
Exemplo:
fonte
ficará bem, se a classe pai imediata
frotz
se definiu ou a herdou.super
é necessário apenas para o suporte adequado à herança múltipla (e funciona apenas se todas as classes o usarem corretamente). Em geral, eleAnyClass.whatever
irá procurarwhatever
nosAnyClass
ancestrais seAnyClass
não o definir / substituir, e isso vale para "classe filho chamando o método dos pais" como para qualquer outra ocorrência!fonte
parent
, está no escopo de toda a classe, não é?O Python 3 possui uma sintaxe diferente e mais simples para chamar o método pai.
Se a
Foo
classe herda deBar
, então fromBar.__init__
pode ser invocado deFoo
viasuper().__init__()
:fonte
Muitas respostas explicaram como chamar um método do pai que foi substituído no filho.
Contudo
também pode significar apenas:
Você pode chamar métodos herdados de uma classe pai, como se fossem métodos da classe filho, desde que não tenham sido substituídos.
por exemplo, em python 3:
Sim, isso pode ser bastante óbvio, mas eu sinto que, sem apontar isso, as pessoas podem deixar esse segmento com a impressão de que você precisa pular coisas ridículas apenas para acessar métodos herdados em python. Especialmente porque essa pergunta é altamente avaliada em pesquisas sobre "como acessar o método de uma classe pai em Python", e o OP é escrito da perspectiva de alguém novo no python.
Eu achei: https://docs.python.org/3/tutorial/classes.html#inheritance útil para entender como você acessa métodos herdados.
fonte
self.string
não fará nada. No entanto, na classe C você ainda pode ligarB().bar(string)
Aqui está um exemplo do uso de super () :
fonte
Também existe um super () em Python. É um pouco instável, por causa das classes de estilo antigo e novo do Python, mas é bastante comum, por exemplo, nos construtores:
fonte
Eu recomendaria usar
CLASS.__bases__
algo assimfonte
Se você não sabe quantos argumentos você pode obter e deseja transmiti-los para a criança também:
(From: Python - Maneira mais limpa de substituir __init__ onde um kwarg opcional deve ser usado após a chamada super ()? )
fonte
Também existe um super () em python.
Exemplo de como um método de superclasse é chamado de um método de subclasse
Este exemplo é semelhante ao explicado acima.No entanto, há uma diferença que super não possui argumentos passados para ele.Este código acima é executável na versão python 3.4.
fonte
Neste exemplo
cafec_param
é uma classe base (classe pai) eabc
é uma classe filho.abc
chama oAWC
método na classe base.Resultado
fonte
No Python 2, não tive muita sorte com o super (). Eu usei a resposta do jimifiki neste tópico SO, como se referir a um método pai em python? . Em seguida, adicionei meu toque pessoal, que acho que é uma melhoria na usabilidade (especialmente se você tiver nomes de classe longos).
Defina a classe base em um módulo:
Em seguida, importe a classe para outros módulos
as parent
:fonte
class A(object):
em vez declass A():
seguida super () irá funcionarfonte
fonte
Este é um método mais abstrato:
fonte
super(self.__class__, self).baz(arg)
.