父类的@staticmethod能否调用子类实现的@staticmethod+@abstractmethod?
问题解答:父类静态方法如何调用子类的抽象静态方法实现
这个问题的核心在于静态方法(staticmethod)不支持多态——这也是你调用B.bar()却没得到预期输出的原因。
为什么当前代码不生效?
在父类A的bar方法里,你直接写了A.foo(),这相当于硬编码绑定了父类的foo静态方法。静态方法本质上就是挂在类命名空间下的普通函数,它不会感知类的继承关系,也不会根据调用它的子类动态切换实现。哪怕子类B重写了foo,父类里的A.foo()依然只会调用A本身的抽象方法(也就是那个空的pass),自然不会有任何输出。
怎么让父类调用子类的实现?
最优雅且符合Python设计思路的方案是把静态方法改成类方法(classmethod),因为类方法会自动接收当前调用的类作为第一个参数(通常命名为cls),天然支持多态:
from abc import ABC, abstractmethod class A(ABC): @classmethod @abstractmethod def foo(cls): pass @classmethod def bar(cls): cls.foo() # 这里用cls而非A,动态绑定当前类的foo方法 class B(A): @classmethod def foo(cls): print("B.foo") B.bar() # 现在会正常输出"B.foo"
当你调用B.bar()时,cls参数会自动传入B类,所以cls.foo()就会调用B中实现的foo方法,完全符合你的预期。
(不推荐)如果一定要保留静态方法?
如果因为某种原因必须使用静态方法,你只能在子类中重写bar方法,显式调用子类的foo:
class B(A): @staticmethod def foo(): print("B.foo") @staticmethod def bar(): B.foo() # 直接调用B的静态方法
但这种方式完全违背了代码复用的原则,每个子类都要重复实现bar,所以非常不推荐。
总结
静态方法不适合需要多态的场景,类方法才是处理这种“父类调用子类实现”需求的正确工具——它能动态关联当前调用的类,完美实现你想要的效果。
内容的提问来源于stack exchange,提问作者Jesus Iniesta
相关产品推荐
相关产品推荐

