在Python中重写静态方法

70 投票
3 回答
43403 浏览
提问于 2025-04-15 11:44

在这里提到的关于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",但实际上并没有(而是打印了 "Called method_two")。

3 个回答

0

另外,如果你想在没有实例的情况下调用“虚拟静态”函数,可以按照以下步骤进行:

  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)
    

请注意,这种方法在你有一个变量“class_type”,而这个变量只有在运行时才能知道的时候特别有用。

3

你看到的这种行为是正常的。静态方法就是...静态的。当你调用在 Test 里定义的 method_three() 时,它肯定会调用同样在 Test 里定义的 method_two()

至于怎么“绕过”这种正常的行为...

最好的办法是当你想要虚拟行为时,就把方法定义为虚拟方法。如果你在使用某个库的代码,而这个库里的静态方法你希望它是虚拟的,那么你可以深入看看,看看是不是有原因,或者只是个疏忽。

否则,你可以在 T2 里定义一个新的 method_three(),让它调用 T2.method_two()

95

在你使用的这个形式中,你明确指定了要调用哪个类的静态方法method_two。如果method_three是一个类方法,并且你调用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

撰写回答