Pergunta

Ao criar uma hierarquia de objetos simples em Python, eu gostaria de ser capaz de chamar métodos da classe pai de uma classe derivada. Em Perl e Java, há uma palavra-chave para este ( super ). Em Perl, eu poderia 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 citar a classe pai explicitamente a partir da criança. No exemplo acima, eu teria que fazer algo como Foo::frotz().

Este não parece certo, uma vez que este comportamento faz com que seja difícil fazer hierarquias profundas. Se as crianças precisam saber que classe definido um método herdado, em seguida, todos os tipos de dor informação é criada.

Esta é uma limitação real em python, uma lacuna no meu entendimento ou ambos?

Foi útil?

Solução

Outras dicas

Python também tem Super assim:

super(type[, object-or-type])

retornar um objeto proxy que método delegados chamadas para um pai ou irmão classe do tipo. Isso é útil para acessar métodos herdados que tenham sido substituído em uma classe. A ordem de pesquisa é a mesma que a utilizada por getattr (), exceto que o próprio tipo é ignorado.

Exemplo:

class A(object):     # deriving from 'object' declares A as a 'new-style-class'
    def foo(self):
        print "foo"

class B(A):
    def foo(self):
        super(B, self).foo()   # calls 'A.foo()'

myB = B()
myB.foo()
ImmediateParentClass.frotz(self)

vai ficar bem, se a classe pai imediato definiu-se frotz ou herdou. super só é necessária para o suporte adequado de múltipla herança (e, em seguida, ele só funciona se todas as classes usa-lo corretamente). Em geral, AnyClass.whatever vai olhar para cima whatever em ancestrais de AnyClass se AnyClass não define / substituí-lo, e isso vale para "class criança chamando o método do pai", como para qualquer outra ocorrência!

Python 3 tem uma sintaxe diferente e mais simples para chamar o método pai.

Se herda classe Foo de Bar, em seguida, a partir Bar.__init__ pode ser chamado de Foo via super().__init__():

class Foo(Bar):

    def __init__(self, *args, **kwargs):
        # invoke Bar.__init__
        super().__init__(*args, **kwargs)

Muitas respostas têm explicou como chamar um método do pai, que foi substituído na criança.

No entanto

"Como você chama o método de um classe pai da classe filha?"

poderia também significar apenas:

"Como você chama métodos herdados?"

Você pode chamar métodos herdados de uma classe pai apenas como se fossem métodos da classe criança, contanto que eles não foram substituídos.

por exemplo. em python 3:

class A():
  def bar(self, string):
    print("Hi, I'm bar, inherited from A"+string)

class B(A):
  def baz(self):
    self.bar(" - called by baz in B")

B().baz() # prints out "Hi, I'm bar, inherited from A - called by baz in B"

Sim, isso pode ser bastante óbvio, mas eu sinto que sem apontar isto as pessoas podem deixar esta discussão com a impressão de que você tem que saltar através de aros ridículos apenas para acesso métodos herdados em python. Especialmente porque este taxas questão muito em pesquisas para "como acessar o método de um classe pai em Python", e o OP é escrito a partir da perspectiva de alguém novo para python.

eu encontrei: https://docs.python.org/3/tutorial/classes.html#inheritance para ser útil na compreensão de como você acessar métodos herdados.

Aqui está um exemplo do uso super () :

#New-style classes inherit from object, or from another new-style class
class Dog(object):

    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self):
        self.moves.append('walk')
        self.moves.append('run')

    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super(Superdog, self).moves_setup()
        self.moves.append('fly')

dog = Superdog('Freddy')
print dog.name # Freddy
dog.moves_setup()
print dog.get_moves() # ['walk', 'run', 'fly']. 
#As you can see our Superdog has all moves defined in the base Dog class

Há uma super () em Python também. É um pouco frouxo, porque de aulas de idade- e novo estilo do Python, mas é muito comumente usado por exemplo em construtores:

class Foo(Bar):
    def __init__(self):
        super(Foo, self).__init__()
        self.baz = 5

Eu recomendaria usar CLASS.__bases__ algo como isto

class A:
   def __init__(self):
        print "I am Class %s"%self.__class__.__name__
        for parentClass in self.__class__.__bases__:
              print "   I am inherited from:",parentClass.__name__
              #parentClass.foo(self) <- call parents function with self as first param
class B(A):pass
class C(B):pass
a,b,c = A(),B(),C()

Se você não sabe quantos argumentos que você pode obter, e quer passá-los durante todo para a criança, bem como:

class Foo(bar)
    def baz(self, arg, *args, **kwargs):
        # ... Do your thing
        return super(Foo, self).baz(arg, *args, **kwargs)

(De: Python -? Cleanest maneira de substituir __init__ onde um kwarg opcional deve ser utilizado após a chamada super () )

Há uma super () em Python também.

Exemplo de como um método de classe super é chamado de um método sub classe

class Dog(object):
    name = ''
    moves = []

    def __init__(self, name):
        self.name = name

    def moves_setup(self,x):
        self.moves.append('walk')
        self.moves.append('run')
        self.moves.append(x)
    def get_moves(self):
        return self.moves

class Superdog(Dog):

    #Let's try to append new fly ability to our Superdog
    def moves_setup(self):
        #Set default moves by calling method of parent class
        super().moves_setup("hello world")
        self.moves.append('fly')
dog = Superdog('Freddy')
print (dog.name)
dog.moves_setup()
print (dog.get_moves()) 

Este exemplo é semelhante ao que explicou above.However há uma diferença que o super não tem nenhum argumentos passados ??para it.This acima código é executável em Python 3.4 versão.

Em Python 2, eu não tenho uma sorte muito com super (). Eu usei a resposta de jimifiki sobre este tópico SO como fazer referência a um método pai em python ? . Então, eu adicionei minha própria pequena torção para ele, que eu acho que é uma melhoria na usabilidade (Especialmente se você tem nomes de classe de comprimento).

Defina a classe base em um módulo:

 # myA.py

class A():     
    def foo( self ):
        print "foo"

Em seguida, importe a classe em outro as parent módulos:

# myB.py

from myA import A as parent

class B( parent ):
    def foo( self ):
        parent.foo( self )   # calls 'A.foo()'

Neste exemplo cafec_param é uma classe base (classe pai) e abc é uma classe filha. abc chama o método AWC na classe base.

class cafec_param:

    def __init__(self,precip,pe,awc,nmonths):

        self.precip = precip
        self.pe = pe
        self.awc = awc
        self.nmonths = nmonths

    def AWC(self):

        if self.awc<254:
            Ss = self.awc
            Su = 0
            self.Ss=Ss
        else:
            Ss = 254; Su = self.awc-254
            self.Ss=Ss + Su   
        AWC = Ss + Su
        return self.Ss
         

    def test(self):
        return self.Ss
        #return self.Ss*4

class abc(cafec_param):
    def rr(self):
        return self.AWC()


ee=cafec_param('re',34,56,2)
dd=abc('re',34,56,2)
print(dd.rr())
print(ee.AWC())
print(ee.test())

saída

56

56

56

class department:
    campus_name="attock"
    def printer(self):
        print(self.campus_name)

class CS_dept(department):
    def overr_CS(self):
        department.printer(self)
        print("i am child class1")

c=CS_dept()
c.overr_CS()
class a(object):
    def my_hello(self):
        print "hello ravi"

class b(a):
    def my_hello(self):
    super(b,self).my_hello()
    print "hi"

obj = b()
obj.my_hello()

Este é um método mais abstrato:

super(self.__class__,self).baz(arg)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top