简单的Python插件系统

0 投票
4 回答
1498 浏览
提问于 2025-04-15 12:18

我正在用Python写一个解析器,专门用来处理内部的基于XML的元数据格式。我需要为不同的标签提供不同的处理类。因为需要处理的标签种类比较多,所以我想把它设计成一个简单的插件系统。我的想法是加载一个包里的所有类,然后把它们注册到我的解析器里。
我现在的尝试是这样的:
(Handlers是一个包含处理类的包,每个处理类都有一个静态成员tags,它是一个字符串的元组)

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 这个变量。

0

首先,抱歉代码格式不太好或者有错误。
也谢谢你们来帮忙看这个问题。不过,问题的根源,像往常一样,其实是在我自己身上。我把类和模块起了同样的名字,搞得自己很困惑。我的 my_import 的结果是一个叫 areaHandler 的模块。而我想要的是一个同样叫 areaHandler 的类。所以我只需要通过 eval('Handlers.' + handler + '.' + handler) 来选出这个类就行了。
再次感谢你们的时间,抱歉占用了你们的带宽。

撰写回答