Python:自动调用所有继承的类
Python: automatically call all inherited classes
在我的示例中,我有一个基础 class 处理,它处理所有预处理和 post 处理。这个 class 意味着在实现算法时继承自。实施后,我想调用所有继承的实例并比较结果。我想知道的是:有没有一种方法可以自动调用所有继承的实例而无需手动调用。甚至更好:有没有办法检测所有继承的 classes,这样我就不需要在任何地方做任何“簿记”?为了更好地解释我的问题,我写了一个小例子:
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()
...
您可以使用BaseProcessing.__subclasses__()
来获取class使用BaseProcessing
作为基础class的列表.我想,你可以这样做:
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()
有点不清楚你想做什么,但听起来你想要一个父 class 的所有实现的集中注册表。一旦有了它,您就可以编写函数来出于任何目的对其进行迭代。
This earlier Q&A looks at some ways of doing that. A class decorator 可能是执行注册的好方法。当然 (?) 理想的情况是在您 subclass; 时自动进行注册; meta-class 可能会让你这样做,你需要进行实验(或者找比我更了解他们的人)。
在我的示例中,我有一个基础 class 处理,它处理所有预处理和 post 处理。这个 class 意味着在实现算法时继承自。实施后,我想调用所有继承的实例并比较结果。我想知道的是:有没有一种方法可以自动调用所有继承的实例而无需手动调用。甚至更好:有没有办法检测所有继承的 classes,这样我就不需要在任何地方做任何“簿记”?为了更好地解释我的问题,我写了一个小例子:
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()
...
您可以使用BaseProcessing.__subclasses__()
来获取class使用BaseProcessing
作为基础class的列表.我想,你可以这样做:
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()
有点不清楚你想做什么,但听起来你想要一个父 class 的所有实现的集中注册表。一旦有了它,您就可以编写函数来出于任何目的对其进行迭代。
This earlier Q&A looks at some ways of doing that. A class decorator 可能是执行注册的好方法。当然 (?) 理想的情况是在您 subclass; 时自动进行注册; meta-class 可能会让你这样做,你需要进行实验(或者找比我更了解他们的人)。