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

如何通过工厂方法直接调用父类__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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:53:22