如何在Python中向类变量注册方法?
我正在编写一个程序,将XML文档集合转换为HTML。这些文档需要类似但不完全相同的转换,因此我希望将大部分细节抽象到一个通用的如何在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'})
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')
。很好,解决了我原来的问题和我不知道的问题!我将让装饰程序将字典转换为元组,以便保留更好的调用语法。