我正在編寫一個程序來將XML文檔集合轉換爲HTML。這些文檔需要類似但不完全相同的轉換,所以我希望將大部分細節抽象爲一個通用的BaseParser
類,然後爲封裝特定於文檔的轉換的每個文檔編寫一個單獨的子類。我正在使用Python標準庫xml.etree.ElementTree
包進行基於事件的分析。如何在Python中向類變量註冊方法?
我希望能夠編寫這樣的代碼,其中函數的邏輯與應該調用時的邏輯捆綁在一起。
class CustomParser(BaseParser):
@on_tag('word', {'lang':'en'})
def found_en_word(self, tag, attrs):
# do something
對於這項工作,裝飾需要註冊在一個類變量的found_en_word
函數(或一個實例變量,雖然這將是冗餘的每個實例具有其自己的副本),從而控制流可以在BaseParser
課中分開。
我現在的解決方案,如下所示,是使用元類創建一個callbacks
字典的類。
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中使用或不使用元類實現嗎?
良好的發現,解決了我原來的問題和我不知道的問題!我將讓裝飾器將字典轉換爲元組,以便我可以保留更好的調用語法。 – iafisher