2009-05-21 14 views
38

Nawiązując do first answer o metodach związanych i niezwiązanych Pythona tutaj mam pytanie:Przesłanianie metody statyczne w Pythonie

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() 

produkuje wyjście:

Called method_one 
Called method_two 
Called method_two 
Called method_two 

Czy istnieje sposób aby przesłonić metoda statyczna w python?

Spodziewałem się, że b_test.method_three() wydrukuje "T2", ale tak się nie stanie (zamiast tego drukuje "Called method_two").

Odpowiedz

49

W formularzu, którego tam używasz, wyraźnie określasz, do którego połączenia telefonicznego ma być klasa method_two. Jeśli method_three był classmethod, a nazywa cls.method_two, co można uzyskać wyniki, które chciały:

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

Wielkie dzięki! Tego właśnie chciałem. – Emma

+3

Naprawdę przydatne. W moim przypadku potrzebowałem dostępu do klasy instancji. Zrobiłem to tak: 'instance .__ class __. My_method()' – Caumons

3

Zachowanie widzisz to oczekiwane zachowanie. Metody statyczne są ... statyczne. Gdy zadzwonisz pod numer method_three() zdefiniowany w Test, na pewno zadzwonisz pod numer method_two() zdefiniowany przez Test.

chodzi o jak „obejść” to prawidłowe zachowanie ...

Najlepszym sposobem jest stworzenie metody wirtualne, gdy chcesz wirtualny zachowanie. Jeśli utknąłeś z jakimś kodem bibliotecznym za pomocą statycznej metody, która ma być wirtualna, możesz zajrzeć głębiej, by sprawdzić, czy jest jakiś powód, czy jest to tylko niedopatrzenie.

W przeciwnym razie można zdefiniować nowy method_three() w T2, który wywołuje T2.method_two().

0

Dodatkowo, jeśli chcesz zadzwonić do „wirtualnego statyczny” funkcjonować bez instancji, można postępować tak:

  1. Deklaracja funkcji w klasie bazowej niestatyczny tak:

    class Base: 
        def my_fun(self): 
         print('my_fun base') 
    
    class Derived(Base): 
        def my_fun(self): 
         print('my_fun derived') 
    
  2. nazwać to przez przepuszczenie typ klasy, który nie jest instancją, tak jak:

    Derived.my_fun(Derived) 
    

Uwaga: jest to przydatne, jeśli masz zmienną "class_type", która jest znana tylko podczas pracy.

+0

W tym momencie, dlaczego nie po prostu uczynić go metodą klasy? Następnie można go przesłonić i nadal wywoływać statycznie (nie trzeba przekazywać parametru klasy). –