如何通过工厂方法直接调用父类__init__创建子类B实例?
问题:如何通过工厂方法创建仅由父类A初始化的B实例?
背景
现有抽象类A与具体子类B,B的构造方法被大量代码依赖。需新增一种构造B实例的方式且不影响原有依赖代码——通过新的工厂方法直接调用B的父类A的构造方法来创建B实例。
重构前代码
from abc import ABC class A(ABC): def __init__(self, k, l, m, n): # complex initialization ... self._x = x self._y = y class B(A): def __init__(self, k, l, m, n): super().__init__(k, l, m, n) # additional code here for initializing B's side
重构后代码
from abc import ABC class A(ABC): def __init__(self, x, y): self._x = x self._y = y @classmethod def _complex_initialization(cls, k, l, m, n): # <<< complex initialization code here that uses cls >>>> return x, y class B(A): def __init__(self, k, l, m, n): x, y = self._complex_initialization(k, l, m, n) super().__init__(x, y) @classmethod def _create_from_x_y(cls, x, y): # is this correct? I need an instance of B but # initialized using the constructor of A return super(B, A).__init__(x, y)
核心疑问
B._create_from_x_y(x, y)方法是否正确?需要该方法能创建仅通过A的构造方法初始化的B实例,不执行B自己__init__里的额外逻辑。
回答
当前的_create_from_x_y写法完全错误,super(B, A).__init__(x, y)不会创建B实例,反而会因为没有绑定实例对象直接报错。
要实现需求,你需要绕开B的__init__,直接创建B实例后用A的构造逻辑初始化,正确写法如下:
@classmethod def _create_from_x_y(cls, x, y): # 创建B实例但不触发任何__init__方法 instance = cls.__new__(cls) # 调用A的__init__来初始化这个B实例 A.__init__(instance, x, y) return instance
关键说明
cls.__new__(cls):负责生成B类型的实例对象,但不会执行任何类的__init__方法,完美避开B自己的初始化逻辑。A.__init__(instance, x, y):手动把刚创建的B实例传入A的构造方法,用A的逻辑初始化_x、_y属性。- 最终返回的实例是B类型,但只经过了A的初始化流程,完全不涉及B
__init__里的额外代码。
注意事项
- 这种写法属于非常规操作,仅适合你明确不需要B的初始化逻辑的场景,如果B有必须初始化的属性,用这个方法创建的实例会缺失这些属性。
- 建议在代码中添加注释说明该方法的用途,避免其他开发者误解。
内容的提问来源于stack exchange,提问作者SkyWalker
相关产品推荐
相关产品推荐

