通过注册表从字符串解析类

时间:2019-04-09 09:46:35

标签: python python-3.x design-patterns

让我们考虑一下我有几个模块:

SomeModules\
    module1.py
    module2.py
    module3.py
main_module.py

main_module.py具有两个类: Aggregator AggregatorElement

class Aggregator:
    _aggregator_element_list = None

    def __init__(self):
        _aggregator_element_list = list()

    def add_element(self, element):
        self._aggregator_element_list.add(element)

    def remove_element(self, idx):
        self._aggregator_element_list.remove(idx)


class AggregatorElement(ABC):
    name = None

    def __init__(self, name):
        self.name = name

    @abstractmethod
    def type():
        raise NotImplementedError

现在,所有这些 module1 module2 module3 都为AggregatorElement类提供了某种特定的实现。假设它们都实现了抽象方法type(),该方法返回一个字符串表示形式。

现在,我有一个文本文件,其中包含与 type()方法返回的字符串匹配的字符串列表。我希望 Aggregator 类加载此文本文件,并从适当的模块(创建对象并将其添加到列表中)将字符串解析为其实现。

完成此任务的最佳方法是什么?我可以正确处理吗?

当所有内容都在同一模块中时的示例:

generator_registry = {}


def creatable(cls):
    if cls.handles_type() in generator_registry:
        raise KeyError("Duplicate string representations found for string: " + cls.handles_type())

    generator_registry[cls.handles_type()] = cls

    return cls

现在使用@creatable装饰器,我将注释每个AggregatorElement实现,并在模块初始化后将它们添加到generator_registry中。

1 个答案:

答案 0 :(得分:0)

您不能在超级班上上所有的儿童班。一种可能的解决方案是创建一个字典,该字典将type()返回的字符串与该类进行匹配。注意:我将您的函数type()重命名为get_string_repr(),因为type是内置方法。

strings_classes = {SubAgg.get_string_repr(): SubAgg, SubAgg2.get_string_repr(), SubAgg2}
# Result: {"Example text": SubAgg, "Another text": SubbAgg2}

这是可能的,因为在python中所有都是对象。您现在可以使用以下方法获取字符串的子类:

subclass = strings_classes[string_rep]

现在,您可以创建子类的对象并使用它们。

aggregator = subclass()
aggregator.add_elemnt(some_element)

编辑:

我与您的装饰器实现了一些东西。

  

简而言之:只需将generator_registry对象导入上层模块即可。

main_module.py

from SomeModules import A, B
import SomeModules

if __name__ == '__main__':
    print(SomeModules.generator_registry)

SomeModules。__init__。py


generator_registry = {}


def creatable(cls):
    if cls.handles_type() in generator_registry:
        raise KeyError("Duplicate string representations found for string: " + cls.handles_type())

    generator_registry[cls.handles_type()] = cls
    return cls

然后是一个子类: SomeModules.A.py

from SomeModules import creatable


@creatable
class A:

    @staticmethod
    def handles_type():
        return "A"

这是您想要的还是我想念任何方面?