Overriding a static method in python
In the form that you are using there, you are explicitly specifying what class's static method_two
to call. If method_three
was a classmethod, and you called cls.method_two
, you would get the results that you wanted:
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_onea_test.method_two() # -> Called method_twoa_test.method_three() # -> Called method_twob_test = T2()b_test.method_three() # -> T2Test.method_two() # -> Called method_twoT2.method_three() # -> T2
The behavior you see is the expected behavior. Static methods are... static. When you call method_three()
defined in Test
it will certainly call method_two()
defined by Test
.
As for how to "get around" this proper behavior...
The very best way is to make methods virtual when you want virtual behavior. If you're stuck with some library code with a static method that you wish were virtual then you might look deeper to see if there's a reason or if it's just an oversight.
Otherwise, you can define a new method_three()
in T2
that calls T2.method_two()
.
Additionally, if you want to call the "virtual static" function without an instance, you could proceed like so:
Declare the function in the base class non-static like so:
class Base: def my_fun(self): print('my_fun base')class Derived(Base): def my_fun(self): print('my_fun derived')
Call it by passing the class type, which is not an instance, like so:
Derived.my_fun(Derived)
Note, this is useful if you have a variable "class_type", which is only known during run time.