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

子类重写__new__返回父类实例是否属于Python反模式?

问题1:这是否是个糟糕的思路?如果是的话,正确的实现方式是什么?

是非常糟糕的思路,完全违反了面向对象继承的基本约定:子类的实例应当满足isinstance(子类实例, 子类) == True,你当前的实现中isinstance(Teacher("Bob"), Teacher)会返回False,会给所有读代码的人造成严重的认知混淆,后续维护极容易出bug。

你要实现「固定部分参数创建父类实例」的需求,有两种完全无副作用、符合直觉的实现方式:

  • 普通工厂函数实现:和你原有调用语法完全一致,类型也完全正确
    class Person:
        def __init__(self, name: str, profession: str):
            self.name = name
            self.profession = profession
    
    # 直接把Teacher定义为工厂函数,调用逻辑和你原写法没有任何区别
    def Teacher(name: str) -> Person:
        return Person(name=name, profession="teacher")
    
    rita = Person("Rita", profession="surgeon")
    bob = Teacher("Bob")
    
  • 父类类方法实现:适合同类固定参数创建的场景比较多的情况,代码更聚合
    from typing import Self
    
    class Person:
        def __init__(self, name: str, profession: str):
            self.name = name
            self.profession = profession
        
        @classmethod
        def create_teacher(cls, name: str) -> Self:
            return cls(name=name, profession="teacher")
    
    bob = Person.create_teacher("Bob")
    

问题2:这是已被公认的设计模式吗?

不是,这种实现属于典型的反模式。你要实现的需求本身属于工厂模式的适用场景,但常规的工厂模式不会通过「继承+重写__new__返回父类实例」这种反直觉的方式实现,只会用上面提到的工厂函数、类方法工厂、独立工厂类这几种标准实现。


问题3:常用的类型检查工具能否正确处理这种实现?

完全不能。你示例里已经提到了,类型检查器会默认认为Teacher("Bob")返回的是Teacher类型,但实际运行时返回的是Person类型,会出现大量类型不匹配的隐患:

  • 如果你后续给Teacher类新增了独有的方法,类型检查器会允许你在bob上调用这个方法,但实际运行会直接抛出属性不存在的异常
  • 如果你代码里有isinstance(bob, Teacher)的判断,运行时永远为假,但类型检查器不会给出任何提示
  • 部分开启严格模式的类型检查工具(比如mypy strict模式)可能会直接对你重写__new__的代码抛出告警,但默认配置下只会静默留下类型隐患

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:48:04