Python:自动调用所有继承的类

2024-10-01 09:36:08 发布

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

在我的示例中,我有一个基类处理,它处理所有的预处理和后处理。当实现算法时,该类将从继承。在实现之后,我想调用所有继承的实例并比较结果。我想知道的是:有没有一种方法可以自动调用所有继承的实例,而不必手动调用。或者更好:有没有一种方法可以检测所有继承的类,这样我就不需要在任何地方做任何“簿记”?为了更好地解释我的问题,我写了一个小例子:

class BaseProcessing:
  def __init__(self, _data):
    self.data = _data

  def __call__(self):
    self.do_pre_processing()
    self.do_algorithm()
    self.do_post_processing()

  def do_pre_processing(self):
    """generic preprocessing steps"""
    print("Starting preprocessing")

  def do_algorithm(self):
    raise RuntimeError('Please inherit from this class and implement algorithm.')

  def do_post_processing(self):
    """generic post processing steps"""
    print("Starting post processing")

class SimpleAlgorithm(BaseProcessing):
  def do_algorithm(self):
    print("Simple calculations")


class SplineAlgorithm(BaseProcessing):
  def do_algorithm(self):
    print("Using splines for calculation")
...


if __name__ == "__main__":
    data = getData()

    # is there a way to automate the following code,
    # which automatically can detect all the inherited instances?
    simple = SimpleAlgorithm(data)
    simple()
    spline = SplineAlgorithm(data)
    spline()
    ...


Tags: 实例方法selfdatadefpostpredo
2条回答

可以使用BaseProcessing.__subclasses__()来获取使用BaseProcessing作为基类的类的列表。我想,你可以这样做:

for subclass in BaseProcessing.__subclasses__():
    instance = subclass(data)
    instance()

不过,总的来说,我倾向于使用更明确的东西。可能是这样的:

class Pipeline:
    def __init__(self, data):
        self.data = data
        self.processes = []
        self.result = []
    def register(self, cls):
        self.processes.append(cls)
        return cls
    def run(self):
        for cls in self.processes:
            instance = cls(self.data)
            result.append(instance())
    
pipeline = Pipeline(data)


@pipeline.register
class SimpleAlgorithm(BaseProcessing):
  def do_algorithm(self):
    print("Simple calculations")

@pipeline.register
class SplineAlgorithm(BaseProcessing):
  def do_algorithm(self):
    print("Using splines for calculation")

pipeline.run()

有点不清楚您想做什么,但听起来您希望父类的所有实现都有一个集中的注册表。一旦你有了它,你就可以写函数来迭代它,不管它有什么用途

This earlier Q&A介绍了一些方法。Aclass decorator可能是执行注册的一种好方法。当然(?)这将是理想的注册发生自动任何时候你子类;一个元类可能会让你这么做,你需要进行实验(或者找到比我更了解它们的人)

相关问题 更多 >