2011-10-22 16 views
10

Este código arroja una excepción, AttributeError, "wtf!", porque A.foo() está llamando al B.foo1(), ¿no debería llamar al A.foo1()? ¿Cómo puedo obligarlo a llamar A.foo1() (y cualquier llamada a un método en el interior A.foo() debe llamar A.*)Llamar a un método anulado, superclase a llamadas reemplazadas método

class A(object): 
    def foo(self): 
     print self.foo1() 

    def foo1(self): 
     return "foo" 

class B(A): 
    def foo1(self): 
     raise AttributeError, "wtf!" 

    def foo(self): 
     raise AttributeError, "wtf!" 

    def foo2(self): 
     super(B, self).foo() 

myB = B() 
myB.foo2() 
+1

Básicamente, estás pidiendo a Python que deje de lado la dinámica y los métodos virtuales y * de alguna manera * descubras omitir partes de la cadena de búsqueda de atributos según el lugar donde se define léxicamente una función. No va a pasar. – delnan

Respuesta

5

Está funcionando según lo previsto, ya que el 100% de los lenguajes de programación mundo trabajan. La subclase anula TODOS los métodos de la clase principal.

Sin embargo, si realmente quieres llamar al A.foo1() puedes hacerlo de esta manera (no puedo garantizarlo). Y en cualquier caso, no debes hacer esto ya que esto va en contra de todos los principios de una buena programación.

class A(object): 

    def foo(self): 
     A.foo1(self) 
2

En el código:

def foo2(self): 
    super(B, self).foo() 

auto es una instancia de B.

Cuando un método derivado de A es llamado por una instancia de B va a empezar a buscar en el espacio de nombres de B, y solo si el método no se encuentra (p. Ej., No se reemplaza por B) se utiliza la implementación de A, pero siempre se refiere a sí mismo B. En ningún punto auto es una instancia de A.

6

In clase A en lugar de llamar a los métodos self, debe llamar a los métodos A y pasar el self manualmente.

Esta no es la manera normal de hacer las cosas - debería tener un realmente buena razón para hacerlo así.

class A(object): 
    def foo(self): 
     print A.foo1(self) 

    def foo1(self): 
     return "foo" 

class B(A): 
    def foo1(self): 
     raise AttributeError, "wtf!" 

    def foo(self): 
     raise AttributeError, "wtf!" 

    def foo2(self): 
     super(B, self).foo() 

myB = B() 
myB.foo2() 
-1

Uno puede ver lo que está haciendo Python aquí, pero la forma de anulación es un poco extrema. Tomemos el caso cuando la clase A define 100 atributos y la clase B los hereda y agrega 1 atributo más. Queremos poder tener el __init __() para B llamar al __init __() para A y dejar que el código de B defina solo su único atributo. De manera similar, si definimos un método reset() en A para establecer todos los atributos en cero, entonces el método reset() correspondiente para B debería poder llamar al método reset() para A y luego poner a cero el único atributo B en su lugar de tener que duplicar todo el código de A. Python está dificultando lo que se supone que es una gran ventaja de la programación orientada a objetos; es decir, la reutilización del código. La mejor opción aquí es evitar la anulación de los métodos que realmente queremos reutilizar. Si quieres tener una idea de las complicaciones con Python aquí, prueba este código:

class X(object): 
    def __init__ (self): 
     print "X" 
     self.x = 'x' 
     self.reset() 
     print "back to X" 
    def reset (self): 
     print "reset X" 
     self.xx = 'xx' 

class Y(X): 
    def __init__ (self): 
     print "Y" 
     super(Y,self).__init__() 
     self.y = 'y' 
     self.reset() 
     print "back to Y" 
    def reset (self): 
     print "reset Y" 
     super(Y,self).reset() 
     print "back to reset Y" 
     self.yy = 'yy' 

aY = Y() 

(Para que esto funcione correctamente, retire la self.reset() en __init __() de la clase Y.)

Cuestiones relacionadas