2009-05-21 8 views
38

Riferendosi alla first answer sui metodi legati e non legati di pitone qui, ho una domanda:override un metodo statico in 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 uscita:

Called method_one 
Called method_two 
Called method_two 
Called method_two 

C'è un modo per scavalcare un metodo statico in python?

Mi aspettavo che b_test.method_three() stampi "T2", ma non lo fa (stampa invece "Called method_two").

risposta

49

Nel modulo che si sta utilizzando, si specifica esplicitamente quale classe è statica method_two da chiamare. Se method_three era un classmethod, e si chiama cls.method_two, si dovrebbe ottenere i risultati che si volevano:

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

Grazie mille! Questo è quello che volevo. – Emma

+3

Davvero utile. Nel mio caso, avevo bisogno di accedere alla classe di un'istanza. L'ho fatto in questo modo: 'instance .__ class __. My_method()' – Caumons

3

Il comportamento che si vede è il comportamento previsto. I metodi statici sono ... statici. Quando si chiama method_three() definito in Test, si chiamerà sicuramente method_two() definito da Test.

Per quanto riguarda come "aggirare" il comportamento corretto ...

Il modo migliore è quello di rendere i metodi virtuale quando si desidera un comportamento virtuale. Se sei bloccato con un codice di libreria con un metodo statico che desideri fosse virtuale, potresti guardare più in profondità per vedere se c'è un motivo o se è solo una svista.

In caso contrario, è possibile definire un nuovo method_three() in T2 che chiama T2.method_two().

0

Inoltre, se si desidera chiamare la funzione "virtuale statica" senza un esempio, si potrebbe procedere in questo modo:

  1. dichiarare la funzione nella classe base non statica in questo modo:

    class Base: 
        def my_fun(self): 
         print('my_fun base') 
    
    class Derived(Base): 
        def my_fun(self): 
         print('my_fun derived') 
    
  2. Chiamatela passando il tipo di classe, che non è un caso, in questo modo:

    Derived.my_fun(Derived) 
    

Nota: ciò è utile se si dispone di una variabile "class_type", che è nota solo durante il runtime.

+0

A quel punto, perché non farlo diventare un metodo di classe? Quindi può essere sovrascritto e ancora chiamato staticamente (non è necessario passare il parametro di classe). –