Pregunta

Al crear una jerarquía de objetos simple en Python, me gustaría poder invocar métodos de la clase padre desde una clase derivada. En Perl y Java, hay una palabra clave para esto ( super ). En Perl, podría hacer esto:

package Foo;

sub frotz {
    return "Bamf";
}

package Bar;
@ISA = qw(Foo);

sub frotz {
   my $str = SUPER::frotz();
   return uc($str);
}

En Python, parece que tengo que nombrar la clase principal explícitamente del elemento secundario. En el ejemplo anterior, tendría que hacer algo como Foo :: frotz () .

Esto no parece correcto, ya que este comportamiento dificulta la creación de jerarquías profundas. Si los niños necesitan saber qué clase definió un método heredado, entonces se crea todo tipo de dolor de información.

¿Es esta una limitación real en Python, una brecha en mi entendimiento o ambas?

¿Fue útil?

Solución

Sí, pero solo con clases de nuevo estilo . Utilice la función super () :

class Foo(Bar):
    def baz(self, arg):
        return super(Foo, self).baz(arg)

Para Python 3.x, puedes usar:

class Foo(Bar):
    def baz(self, arg):
        return super().baz(arg)

Otros consejos

Python también tiene super también:

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

  

Devuelva un objeto proxy que delegue las llamadas de método a una clase de tipo padre o hermana.   Esto es útil para acceder a los métodos heredados que se han anulado en una clase.   El orden de búsqueda es el mismo que el que usa getattr (), excepto que el tipo en sí se omite.

Ejemplo:

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)

estará bien, ya sea que la clase padre inmediata definiera frotz en sí misma o la haya heredado. super solo es necesario para el soporte adecuado de la herencia multiple (y luego solo funciona si cada clase lo usa correctamente). En general, AnyClass.whatever buscará whatever en los ancestros de AnyClass si AnyClass no lo hace. Definir / anularlo, y esto es válido para " clase secundaria que llama al método de los padres " como para cualquier otra ocurrencia!

Python 3 tiene una sintaxis diferente y más simple para llamar al método principal.

Si la clase Foo se hereda de Bar , entonces desde Bar .__ init__ puede invocarse desde Foo a través de < código> super () .__ init __ () :

class Foo(Bar):

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

Muchas respuestas han explicado cómo llamar a un método del padre que se ha invalidado en el hijo.

Sin embargo

  

" ¿cómo se llama el método de una clase padre de una clase hija? "

también podría significar simplemente:

  

" ¿cómo se llaman los métodos heredados? "

Puede llamar a métodos heredados de una clase principal como si fueran métodos de la clase secundaria, siempre que no se hayan sobrescrito.

por ejemplo en 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"

sí, esto puede ser bastante obvio, pero creo que sin señalar esto, las personas pueden dejar este hilo con la impresión de que tienes que saltar a través de aros ridículos solo para acceder a los métodos heredados en Python. Especialmente ya que esta pregunta tiene una alta calificación en las búsquedas de "cómo acceder al método de una clase padre en Python", y el OP se escribe desde la perspectiva de alguien nuevo en Python.

He encontrado: https://docs.python.org/3/tutorial/classes.html#inheritance para ser útil para entender cómo acceder a los métodos heredados.

Este es un ejemplo del uso de 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

También hay un super () en Python. Es un poco extraño, debido a las clases de estilo antiguo y nuevo de Python, pero se usa con bastante frecuencia, por ejemplo. en constructores:

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

Recomendaría utilizar CLASS .__ bases__ algo como esto

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()

Si no sabe cuántos argumentos podría obtener, y también quiere transmitirlos al niño:

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

(De: Python: la forma más limpia de anular __init__ donde se debe usar un kwarg opcional después de la llamada super ()? )

También hay un super () en python.

Ejemplo de cómo se llama a un método de superclase desde un método de subclase

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 ejemplo es similar al explicado anteriormente. Sin embargo, hay una diferencia que super no tiene argumentos pasados. Este código anterior es ejecutable en la versión 3.4 de Python.

En Python 2, no tuve mucha suerte con super (). Utilicé la respuesta de jimifiki en este subproceso SO cómo referirse a un método padre en python ? . Luego, le agregué mi propio pequeño giro, que creo que es una mejora en la facilidad de uso (especialmente si tienes nombres de clase largos).

Defina la clase base en un módulo:

 # myA.py

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

Luego importe la clase a otros módulos como padre :

# myB.py

from myA import A as parent

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

en este ejemplo, cafec_param es una clase base (clase primaria) y abc es una clase secundaria. abc llama al método AWC en la clase 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())

Output

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 es un método más abstracto:

super(self.__class__,self).baz(arg)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top