You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python类装饰器检查类是否重写了object的特定方法?

检查类是否重写特定方法的Python风格类装饰器实现

核心思路

要判断子类是否重写了从object继承的方法(比如__str__),最直接且符合Python风格的方式是检查类自身的__dict__中是否存在该方法——子类重写方法时,这个方法会被存入自身的__dict__;如果只是继承父类的方法,子类__dict__里不会有这个键。

没必要用mro()遍历或__bases__查找,原因如下:

  • dir(kls)会返回包括继承方法在内的所有属性,根本区分不出是不是子类自己写的;
  • 用getattr(kls, "__str__") == object.__str__判断有漏洞:如果中间父类重写了__str__但子类没动,getattr拿到的是中间父类的方法,和object.__str__不相等,会误判成子类重写了。

正确实现代码

def check_overridden_method(method_name: str):
    # 做个通用装饰器工厂,支持检查任意方法,复用性更强
    def decorator(kls: type) -> type:
        if method_name in kls.__dict__:
            print(f"类 {kls.__name__} 已重写 {method_name} 方法")
        else:
            print(f"类 {kls.__name__} 未重写 {method_name} 方法")
        return kls
    return decorator

# 专门针对__str__方法的装饰器
check_str_method = check_overridden_method("__str__")

@check_str_method
class ChildClass1:
    pass

@check_str_method
class ChildClass2:
    def __str__(self):
        return "I HAVE OVERRIDDEN __str__"

# 测试输出
obj1 = ChildClass1()
obj2 = ChildClass2()
print("obj1...", str(obj1))
print("obj2...", str(obj2))

额外说明

  1. 通用化设计:把装饰器做成工厂模式,传入不同方法名就能检查对应的方法(比如__repr__、__eq__),不用重复写装饰器逻辑。
  2. 什么时候需要用mro?:如果你的需求是检查整个继承链里有没有类修改过目标方法(而不是当前子类是否重写),那才需要遍历kls.mro(),逐个检查每个类的__dict__。但如果只是判断当前子类自己有没有重写,__dict__完全够用。

内容的提问来源于stack exchange,提问作者Toothpick Anemone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 02:47:11