循环遍历python中的导入类

时间:2014-10-03 20:27:51

标签: python

由于种种原因,我发现自己处于导入许多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.

我的问题是我有很多解析器可以通过,我觉得必须有一种方法来动态迭代导入的类。不得不亲自动手写下这些内容不仅是一种痛苦,它使我的代码的意图更难以在噪音中看到。

3 个答案:

答案 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()函数)等。