简单的python插件系统

时间:2009-06-17 11:57:15

标签: python

我正在为python中的内部基于xml的元数据格式编写解析器。我需要提供不同的类来处理不同的标签。需要一个相当大的处理程序集合,所以我设想它是一个简单的插件系统。我想要做的只是加载包中的每个类,并将其注册到我的解析器。 我目前的尝试看起来像这样:
(Handlers是包含处理程序的包,每个处理程序都有一个静态成员标记,这是一个字符串元组)

class MetadataParser:
    def __init__(self):
        #...
        self.handlers={}
        self.currentHandler=None
        for handler in dir(Handlers): # Make a list of all symbols exported by Handlers
            if handler[-7:] == 'Handler': # and for each of those ending in "Handler"
                handlerMod=my_import('MetadataLoader.Handlers.' + handler)
                self.registerHandler(handlerMod, handlerMod.tags) # register them for their tags

    # ...

    def registerHandler(self, handler, tags):
        """ Register a handler class for each xml tag in a given list of tags """
        if not isSequenceType(tags): 
            tags=(tags,) # Sanity check, make sure the tag-list is indeed a list
        for tag in tags:
            self.handlers[tag]=handler

然而,这不起作用。我收到错误AttributeError: 'module' object has no attribute 'tags' 我究竟做错了什么?

4 个答案:

答案 0 :(得分:0)

您的handlerMod个模块之一可能不包含任何tags变量。

答案 1 :(得分:0)

我建议您阅读this page上的示例和说明,其中介绍了如何编写插件架构。

答案 2 :(得分:0)

首先,对于格式不正确/不正确的代码道歉 还要感谢你看一下。然而,罪魁祸首常常在椅子和键盘之间。我通过拥有相同名称的类和模块来迷惑自己。 my_import的结果(我现在意识到我甚至没有提到它来自哪里......来自SO:link)是一个名为areaHandler的模块。我想要这个类,也叫areaHandler。所以我只需要通过eval('Handlers。'+ handler +'。'+ handler)来挑选类 再次感谢您的时间,并对带宽感到抱歉

答案 3 :(得分:0)

通过extend_me库进行简单且完整的可扩展实现。

代码看起来像

from extend_me import ExtensibleByHash

# create meta class
tagMeta = ExtensibleByHash._('Tag', hashattr='name')

# create base class for all tags
class BaseTag(object):
    __metaclass__ = tagMeta

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

    def process(self, *args, **kwargs):
        raise NotImeplemntedError()

# create classes for all required tags
class BodyTag(BaseTag):
    class Meta:
        name = 'body'

    def process(self, *args, **kwargs):
        pass  # do processing

class HeadTag(BaseTag):
    class Meta:
        name = 'head'

    def process(self, *args, **kwargs):
        pass  # do some processing here

# implement other tags in this way
# ...

# process tags
def process_tags(tags):
    res_tags = []
    for tag in tags:
        cls = tagMeta.get_class(tag)  # get correct class for each tag
        res_tags.append(cls(tag))  # and add its instance to result
    return res_tags

有关详细信息,请查看documentationcode。 此库在OpenERP / Odoo RPC lib

中使用