在Python中重写一个静态方法
在这里提到关于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()
产生输出:
Called method_one Called method_two Called method_two Called method_two
有没有办法在Python中重写静态方法?
我期望b_test.method_three()
打印“T2”,但不打印(改为打印“调用method_two”)。
在你使用的表单中,你明确地指定了要调用哪个类的静态method_two
。 如果method_three
是一个classmethod,并且你调用了cls.method_two
,你会得到你想要的结果:
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
你看到的行为是预期的行为。 静态方法是…静态的。 当您调用method_three()
定义的method_three()
,它肯定会调用由Test
定义的method_two()
。
至于如何“摆脱”这种正确的行为…
当你想要虚拟行为的时候,最好的方法就是让方法变成虚拟的。 如果你用一个你希望是虚拟的静态方法阻塞了一些库代码,那么你可能会更深入地看看是否有一个原因,或者只是一个疏忽。
否则,可以在T2
中定义一个调用T2.method_two()
的新T2.method_two()
。
另外,如果你想在没有实例的情况下调用“虚拟静态”函数,你可以这样做:
-
在基类非静态声明函数如下所示:
class Base: def my_fun(self): print('my_fun base') class Derived(Base): def my_fun(self): print('my_fun derived')
-
通过传递不是实例的类类来调用它,如下所示:
Derived.my_fun(Derived)
请注意,如果您有一个variables“class_type”,只有在运行时才知道这个variables,那么这很有用。