2009-05-21 18 views
38

Refiriéndose a la first answer acerca de los métodos consolidados y no consolidados del pitón aquí, tengo una pregunta:Anulación de un método estático en Python

class Test: 
    def method_one(self): 
     print "Called method_one" 
    @staticmethod 
    def method_two(): 
     print "Called method_two" 
    @staticmethod 
    def method_three(): 
     Test.method_two() 
class T2(Test): 
    @staticmethod 
    def method_two(): 
     print "T2" 
a_test = Test() 
a_test.method_one() 
a_test.method_two() 
a_test.method_three() 
b_test = T2() 
b_test.method_three() 

produce una salida:

Called method_one 
Called method_two 
Called method_two 
Called method_two 

¿Hay una manera de anular una método estático en python?

Esperaba b_test.method_three() imprimir "T2", pero no (imprime "Método llamado_two" en su lugar).

Respuesta

49

En el formulario que está utilizando allí, está especificando explícitamente qué clase estática method_two para llamar. Si method_three fue un classmethod, y se llama cls.method_two, se llega a los resultados que queríamos:

class Test: 
    def method_one(self): 
     print "Called method_one" 
    @staticmethod 
    def method_two(): 
     print "Called method_two" 
    @classmethod 
    def method_three(cls): 
     cls.method_two() 

class T2(Test): 
    @staticmethod 
    def method_two(): 
     print "T2" 

a_test = Test() 
a_test.method_one() # -> Called method_one 
a_test.method_two() # -> Called method_two 
a_test.method_three() # -> Called method_two 

b_test = T2() 
b_test.method_three() # -> T2 
Test.method_two() # -> Called method_two 
T2.method_three() # -> T2 
+0

¡Muchas gracias! Esto es lo que yo quería. – Emma

+3

Realmente útil. En mi caso, necesitaba acceder a la clase de una instancia. Lo hice así: 'instancia .__ clase __. My_method()' – Caumons

3

El comportamiento que se observa es el comportamiento esperado. Los métodos estáticos son ... estáticos. Cuando llame al method_three() definido en Test, ciertamente llamará al method_two() definido por Test.

En cuanto a la manera de "moverse" este comportamiento adecuado ...

La mejor manera es hacer que los métodos virtuales cuando se desea un comportamiento virtual. Si está atascado con algún código de biblioteca con un método estático que desea que sea virtual, entonces puede mirar más a fondo para ver si hay una razón o si es solo un descuido.

De lo contrario, puede definir un nuevo method_three() en T2 que llame al T2.method_two().

0

Además, si desea llamar a la función "virtual estática" sin un ejemplo, podría proceder de este modo:

  1. declarar la función en la clase base no estático, así:

    class Base: 
        def my_fun(self): 
         print('my_fun base') 
    
    class Derived(Base): 
        def my_fun(self): 
         print('my_fun derived') 
    
  2. Call que pasando el tipo de clase, que no es un ejemplo, así:

    Derived.my_fun(Derived) 
    

Nota, esto es útil si tiene una variable "class_type", que solo se conoce durante el tiempo de ejecución.

+0

En ese momento, ¿por qué no simplemente convertirlo en un método de clase? Luego se puede anular y aún llamar estáticamente (no es necesario pasar el parámetro de clase). –

Cuestiones relacionadas