59

参考这里关于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”)。

4

3 回答 3

83

在您在那里使用的表单中,您明确指定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
于 2009-05-21T13:56:59.780 回答
3

您看到的行为是预期的行为。静态方法是……静态的。当你调用method_three()定义在Test它肯定会调用method_two()定义的Test

至于如何“绕过”这种正确的行为......

最好的方法是在您需要虚拟行为时将方法设为虚拟。如果你被一些库代码困住了,你希望它是虚拟的静态方法,那么你可能会更深入地查看是否有原因,或者它是否只是一个疏忽。

否则,您可以method_three()T2该调用中定义一个新的T2.method_two()

于 2009-05-21T14:00:27.353 回答
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”,这将很有用。

于 2016-06-30T09:45:09.350 回答