2010-03-20 11 views
12

Tengo un método privado def __pickSide(self): en una clase para padres que me gustaría anular en la clase para niños. Sin embargo, la clase secundaria aún llama al def __pickSide(self): heredado. ¿Cómo puedo anular la función? El nombre de la función de la clase infantil es exactamente el mismo que el nombre de la función principal.¿Cómo anulo las funciones de una clase padre en python?

+3

No utilice todos los '__'. Ellos son confusos. Realmente no hay "privado" en Python. Hacen que las cosas simples parezcan confusas. Actualice su pregunta con el ejemplo más pequeño de código que muestre su problema. –

+0

Ese es el código con el que estoy teniendo problemas ... ¿qué más quieres? Sé que todavía se puede acceder a las funciones y variables "privadas" en Python, pero ¿no será más confuso usar todas las funciones públicas al usar la clase? – wrongusername

+0

"Ese es el código"? ¿Qué código? ¿Puede actualizar la pregunta para proporcionar realmente una muestra de código real que en realidad no funciona? Es muy difícil adivinar cómo se ve tu código. Es fácil asumir cosas; es fácil suponer que está mal. "¿qué más quieres?" Código. Mirar y ver qué error está cometiendo realmente, no qué error supongo que está cometiendo. –

Respuesta

33

Vamos en el ejemplo más sencillo:

from dis import dis 

class A(object): 
    def __pick(self): 
     print "1" 

    def doitinA(self): 
     self.__pick() 

class B(A): 
    def __pick(self): 
     print "2" 

    def doitinB(self): 
     self.__pick() 

b = B() 
b.doitinA() # prints 1 
b.doitinB() # prints 2 

dis(A.doitinA) 
print 
dis(B.doitinB) 

El desmontaje es el siguiente:

8   0 LOAD_FAST    0 (self) 
       3 LOAD_ATTR    0 (_A__pick) 
       6 CALL_FUNCTION   0 
       9 POP_TOP 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

15   0 LOAD_FAST    0 (self) 
       3 LOAD_ATTR    0 (_B__pick) 
       6 CALL_FUNCTION   0 
       9 POP_TOP 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

Como se puede ver, Python destroza nombres de las funciones que empiezan con dos guiones (y accesos a tales nombres !!) a un nombre que incluye el nombre de la clase - en este caso _A__pick y _B__pick). Eso significa que la clase en la que se define una función determina cuál de los métodos __pick se llama.

La solución es simple, evite los métodos pseudoprivados eliminando los guiones bajos dobles. Por ejemplo, use _pick en lugar de __pick.

5

El problema que está viendo es que el doble de subrayado destruye el nombre de la función incluso en llamadas. Esto evita que el polimorfismo funcione correctamente ya que el nombre con el que está mutilado se basa en el nombre de la clase en la que se define el método, y no en el nombre de la clase del objeto al que se hace referencia. Reemplazar los doble guiones bajos con algo más resolverá esto. mirada

3
  • Usando __foo nombres Mangles el nombre del método para hacerlo más problemas para acceder a él cuando lo necesite. Yo recomendaría nunca usarlos, lo que hace que cosas como las pruebas sean más fáciles.

  • No hay privacidad en Python, y si existiera, evitaría que hiciera esto de todos modos. (Este es el punto de cosas privadas en idiomas que tienen.)

  • La convención común para indicar que un atributo no es parte de la interfaz pública de una clase que utilice un sola subrayado inicial, como _foo . Esto es suficiente para hacer que su código sea claro, separando sus detalles internos de su API pública.

Cuestiones relacionadas