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

另外,如果你想在没有实例的情况下调用“虚拟静态”函数,你可以这样做:

  1. 在基类非静态声明函数如下所示:

     class Base: def my_fun(self): print('my_fun base') class Derived(Base): def my_fun(self): print('my_fun derived') 
  2. 通过传递不是实例的类类来调用它,如下所示:

     Derived.my_fun(Derived) 

请注意,如果您有一个variables“class_type”,只有在运行时才知道这个variables,那么这很有用。