由于种种原因,我发现自己处于导入许多python模块的位置,并希望迭代模块中的每个类。
from capacity_hdd_parser import CapacityHDDParser
from capacity_ssd_parser import CapacitySSDParser
from checksum_parser import ChecksumParser
.
.
.
每个解析器都从基类继承,并且有一个我想在每个解析器上调用的方法
parsers = [CapacityHDDParser, CapacitySSDParser, ChecksumParser]
for parser in parsers:
parser_instance = parser()
data_returned = parser_instance.parse(logset_path)
# Do a bunch of post processing here.
我的问题是我有很多解析器可以通过,我觉得必须有一种方法来动态迭代导入的类。不得不亲自动手写下这些内容不仅是一种痛苦,它使我的代码的意图更难以在噪音中看到。
答案 0 :(得分:4)
如果您在全局命名空间中不需要它们,则可以使用importlib.import_module
。
from importlib import import_module
for module_name, class_name in (('capacity_hdd_parser', 'CapacityHDDParser'),
('capacity_ssd_parser', 'CapacitySSDParser'),
('checksum_parser', 'ChecksumParser')):
data_returned = getattr(import_module(module_name), class_name)().parse(logset_path)
# Other processing here
您可能还需要考虑将解析器类合并到单个包中。它会使这种方法更干,也可能更像Pythonic。每个文件一个类在Python中通常过于冗余/冗长。
答案 1 :(得分:2)
孩子们,不要在家尝试:
parsers = [v for (k, v) in locals().items()
if k.endswith('Parser')]
您可以通过更好的测试条件使其更安全一些。
[更新]
Silas的陈述性方法是安全的选择:
PARSERS = {
'capacity_hdd_parser': 'CapacityHDDParser',
'capacity_ssd_parser': 'CapacitySSDParser',
'checksum_parser': 'ChecksumParser',
...
}
def load_parser(module, parser):
return getattr(importlib.import_module(module), parser)
parsers = [load_parser(*item) for item in PARSERS.items()]
更好的是,您可以使用config file替换PARSERS
dict。
答案 2 :(得分:0)
for Parser in get_registered_parsers():
data = Parser().parse(logset_path)
通过任何必要的方式定义get_registered_parsers()
,包括黑魔法,例如setuptools entry_points,或yapsy (plugin architecture),或ABC(显式register()
函数)等。