如何创建一个新对象,其中一个方法是动态数量的实例化同级类的组合?

2024-05-19 03:38:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我陷入了一个继承/动态方法创建问题。 假设我有一个抽象基类及其子类,如下面的简化示例所示:

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

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

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()函数添加到新的对象实例中。然而,我不确定这在概念上是否正确/良好

欢迎对我对所提出问题的解决方案的总体结构提出任何反馈


Tags: 实例方法selfnewgetreturnobjectdef
1条回答
网友
1楼 · 发布于 2024-05-19 03:38:04

关于您的设计,我想改变以下几点: 首先,我们有一个不同的抽象基类,它封装了真正的基类部分(self.x不是其中之一)。第二,您可以有一个中间基来设置self.x

最后是一个复合类

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需要一些注意

相关问题 更多 >

    热门问题