代码之家  ›  专栏  ›  技术社区  ›  SkyWalker

如何从直接调用super__init__的工厂(即构造函数)创建子类的实例?[已关闭]

  •  -2
  • SkyWalker  · 技术社区  · 1 年前

    我有一个抽象类A和一个具体的子类B。B有一个构造函数,它有一个很大的代码库依赖于它,但现在我需要一种新的方法来构造B的实例,而不影响依赖的代码,所以我需要从一个新的构造函数工厂方法创建一个B的实例并直接调用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的实例。

    1 回复  |  直到 1 年前
        1
  •  1
  •   wjandrea senderle    1 年前

    以下是如何修改_create_from_x_y方法:

    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):
            pass
    
    
    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):
            # Create new instance of B without calling its constructor
            obj = cls.__new__(cls)
            
            # Calling the constructor of A with the instance of B
            A.__init__(obj, x, y)
            
            return obj