如何使用一种方法创建一个新对象,该方法是动态数量的实例化兄弟 类 的组合?

How to create a new object with one method being a combination of a dynamic number of instantiated sibling classes?

我卡在 inheritance/dynamic 方法创建问题上。 假设我有一个抽象基础 class 及其子代,就像这个简化的例子一样:

from abc import ABC, abstractmethod

class MyBaseClass(ABC):
  def __init__(self, x: int):
    self.x = x
    self.y = None
  
  @abstractmethod
  def evaluate(self, val: float) -> float:
    pass
  
  def get_y(self) -> float:
    return self.y

class ChildClass1(MyBaseClass):
  def evaluate(self, val: float) -> float
    self.y = val*val
    return val * self.x

class ChildClass2(MyBaseClass):
  def evaluate(self, val: float) -> float
    self.y = val**0.5
    return val / self.x

# create some instances
c1 = ChildClass1(5)
c2 = ChildClass1(2)
c3 = ChildClass2(10)
c_list = [c1, c2, c3]  # save them as a list

现在我想创建另一个 class,它也是我的基础 class 的 true 子级,但它的 evaluate() 方法是其他子 class 实例 evaluate() 方法的组合。为了实现这一点,我尝试编写一个函数来创建基础 class 的可实例化版本的实例,并为其分配一个新方法:

class GeneralChildClass(MyBaseClass):
  def evaluate(self, val: float) -> float:
    pass

def combine_objects(object_list: list) -> GeneralChildClass:
  new_c = GeneralChildClass(1)  # initial parameter doesnt matter in this example
  settattr(new_c, 'object_list', object_list)
  def new_evaluate(self, val: float) -> float:
    result = 0.0
    new_y = 0
    for c in self.object_list:
      result += c.evaluate(val)
      new_y += c.y
    result = results / len(self.object_list)
    self.y = new_y
    return result
  
  new_c.evaluate = new_evaluate.__get__(new_c, GeneralChildClass)
  return new_c

c4 = combine_objects(c_list)
c4.evaluate(4.5)
c4.get_y()

c5 = combine_objects([c4, c1])  # this should also be possible

通过使用 _get__() 可以将新的 'merged' evaluation() 函数添加到新的对象实例中。但是我不确定这在概念上是否是 correct/good.

欢迎对我提出的问题的解决方案的一般结构提出任何反馈!

我想对您的设计进行一些更改: 首先有一个不同的抽象基础 class 封装了真正的基础部分(self.x 不是其中之一)。其次,您可以有一个中间基础来设置 self.x

最后是复合 class。

from abc import ABC, abstractmethod

class MyBaseClass(ABC):
  def __init__(self):
    self.y = None
  
  @abstractmethod
  def evaluate(self, val: float) -> float:
    pass
  
  def get_y(self) -> float:
    return self.y

class ChildBase(MyBaseClass):
  def __init__(self, x: int):
    super().__init__()
    self.x = x

class ChildClass1(ChildBase):
  def evaluate(self, val: float) -> float
    self.y = val*val
    return val * self.x

class ChildClass2(ChildBase):
  def evaluate(self, val: float) -> float
    self.y = val**0.5
    return val / self.x

class Composite(MyBaseClass):
  def __init__(self, object_list):
    super().__init__()
    self.object_list = object_list

  def evaluate(self, val: float) -> float:
    result = 0.0
    new_y = 0
    for c in self.object_list:
      result += c.evaluate(val)
      new_y += c.y
    result = result / len(self.object_list)
    self.y = new_y
    return result

# create some instances
c1 = ChildClass1(5)
c2 = ChildClass1(2)
c3 = ChildClass2(10)
c_list = [c1, c2, c3]  # save them as a list
c5 = Composite(c_list)
print(c5.evaluate(4))

另请注意,您的 self.y 需要一些注意。