Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中向类变量注册方法?_Python_Python 3.x_Xml Parsing - Fatal编程技术网

如何在Python中向类变量注册方法?

如何在Python中向类变量注册方法?,python,python-3.x,xml-parsing,Python,Python 3.x,Xml Parsing,我正在编写一个程序,将XML文档集合转换为HTML。这些文档需要类似但不完全相同的转换,因此我希望将大部分细节抽象到一个通用的BaseParser类中,然后为每个文档编写一个子类来封装特定于文档的转换。我正在使用Python标准库xml.etree.ElementTree包进行基于事件的解析 我希望能够编写这样的代码,其中函数的逻辑与应该调用它的时间捆绑在一起 class CustomParser(BaseParser): @on_tag('word', {'lang':'en'})

我正在编写一个程序,将XML文档集合转换为HTML。这些文档需要类似但不完全相同的转换,因此我希望将大部分细节抽象到一个通用的
BaseParser
类中,然后为每个文档编写一个子类来封装特定于文档的转换。我正在使用Python标准库
xml.etree.ElementTree
包进行基于事件的解析

我希望能够编写这样的代码,其中函数的逻辑与应该调用它的时间捆绑在一起

class CustomParser(BaseParser):
    @on_tag('word', {'lang':'en'})
    def found_en_word(self, tag, attrs):
        # do something
为了实现这一点,装饰器需要在类变量(或实例变量,尽管每个实例都有自己的副本是多余的)中注册
found\u en\u word
函数,以便在
BaseParser
类中分离控制流

我当前的解决方案(如下所示)是使用元类在类上创建
回调
字典

class Meta(type):
    def __new__(cls, clsname, bases, dct):
        callbacks = {}
        for key, value in dct.items():
            if hasattr(value, '_on_tag'):
                callbacks[value._on_tag] = value
        ret = type(clsname, bases, dct)
        ret.callbacks = callbacks
        return ret

def on_tag(tag, attrs=None):
    def decorator(f):
        f._on_tag = (tag, attrs)
        return f
    return decorator

class BaseParser(metaclass=Meta):
    ...
不幸的是,元类看起来不像我希望的那样被继承:元类似乎被用来构造一个修改过的
BaseParser
类,而
CustomParser
只是从中正常继承


这个构造在Python中可以实现吗,有元类还是没有元类?

您的元类没有正确构造类。如中所述,您实际上需要调用
type.\uuuuu new\uuuu(Meta、clsname、base、dct)
。只需调用
类型(clsname、base、dct)
,就可以构造一个普通类,而不是自定义元类的实例


一旦您解决了这个问题,您将遇到另一个问题,即您试图使用标签上的
\u
作为字典键,但是标签上的
\u
包含字典,并且字典不能散列。这与你的主要问题有点相切,但你必须想办法处理它(也许是让用户在标签上做
@on_-tag('word',('lang','en'))
而不是在标签上做
@on_-tag('word',{'lang','en')

很好,解决了我原来的问题和我不知道的问题!我将让装饰程序将字典转换为元组,以便保留更好的调用语法。