2011-10-20 22 views
13

Me gustaría un método en una clase base para llamar a otro método en la misma clase en lugar del método de anulación en una clase heredada. Me gustaría que el siguiente código para imprimirMétodo de herencia y clase base llamada python

Clase B: 6

Clase A: 9

se puede hacer esto?


# Base class definition 
class ClassA(object): 
    def __init__(self): 
     print("Initializing A") 

    # hoping that this function is called by this class's printFnX 
    def fnX(self, x): 
     return x**2 

    def printFnX(self, x): 
     print("ClassA:",self.fnX(x)) 

# Inherits from ClassA above 
class ClassB(ClassA): 
    def __init__(self): 
     print("initizlizing B") 

    def fnX(self, x): 
     return 2*x 

    def printFnX(self, x): 
     print("ClassB:", self.fnX(x)) 
     ClassA.printFnX(self,x) 

bx = ClassB() 
bx.printFnX(3) 
+10

¿Considera reconsiderar qué respuesta ha marcado como aceptada? la selección actual es realmente un mal consejo para la mayoría de las personas y la mayoría de los casos de uso. –

Respuesta

-3

Lo mismo se puede lograr haciendo fnX y printFnX ambos classmethods.

class ClassA(object): 

    def __init__(self): 
     print("Initializing A") 

    # hoping that this function is called by this class's printFnX 
    @classmethod 
    def fnX(self, x): 
     return x ** 2 

    @classmethod 
    def printFnX(self, x): 
     print("ClassA:",self.fnX(x)) 

class ClassB(ClassA): 
    def __init__(self): 
     print("initizlizing B") 

    def fnX(self, x): 
     return 2*x 

    def printFnX(self, x): 
     print("ClassB:", self.fnX(x)) 
     ClassA.printFnX(x) 


bx = ClassB()<br> 
bx.printFnX(3) 
+0

Esto es mejor que la otra respuesta ... más elegante. Gracias. – fodon

+5

Esto ni siquiera funciona. Intente acceder a una variable de instancia como '' self.y'' desde dentro de fnX. En un método de clase, la variable * self * ya no contiene la instancia; en su lugar, se convierte en la clase de la instancia de la persona que llama, por lo que ha perdido completamente el acceso a las variables de instancia. Este "patrón" es un desastre y algo que no debería usarse en el código que le importa. –

+0

Estoy de acuerdo, acaba de responder a su pregunta original, eso es con todos los inconvenientes que acaba de describir. No hay un patrón aquí per se. –

49

Felicidades, usted ha descubierto el caso de uso motivador para el nombre de doble subrayado de Python mangling :-)

Para los detalles y un ejemplo práctico de salida ver: http://docs.python.org/tutorial/classes.html#private-variables y al http://docs.python.org/reference/expressions.html#atom-identifiers.

Aquí es cómo usarlo para su ejemplo:

# Base class definition 
class ClassA(object): 
    def __init__(self): 
     print("Initializing A") 

    # hoping that this function is called by this class's printFnX 
    def fnX(self, x): 
     return x**2 
    __fnX = fnX 

    def printFnX(self, x): 
     print("ClassA:",self.__fnX(x)) 

# Inherits from ClassA above 
class ClassB(ClassA): 
    def __init__(self): 
     print("initizlizing B") 

    def fnX(self, x): 
     return 2*x 

    def printFnX(self, x): 
     print("ClassB:", self.fnX(x)) 
     ClassA.printFnX(self,x) 

bx = ClassB() 
bx.printFnX(3) 

El caso de uso se describe como una forma de implementar el Open-Closed Principle en "El arte de la subclasificación" que se encuentra en http://www.youtube.com/watch?v=yrboy25WKGo&noredirect=1.

+1

Muy perspicaz. ¡Ahora sé para qué es útil el nombre doble de subrayado de los métodos! –

+0

Lo que podría no ser obvio es que los métodos en la clase base deben ser públicos o debe usar el nombre completamente destrozado. Python no tiene un calificador "protegido" o "amigo", por lo que al refactorizar simplemente mover 'def __doSomething (self): 'de la superclase a la clase base no lo hará accesible desde la superclase. Tendrás que hacerlo público 'def doSomething (self): 'o usar el nombre destrozado. –

Cuestiones relacionadas