lxml.objectify似乎没有为我的自定义元素类调用构造函数:
from lxml import objectify, etree
class CustomLookup(etree.CustomElementClassLookup):
def lookup(self, node_type, document, namespace, name):
lookupmap = { 'custom' : CustomElement }
try:
return lookupmap[name]
except KeyError:
return None
class CustomElement(etree.ElementBase):
def __init__(self):
print("Made CustomElement")
parser = objectify.makeparser()
parser.set_element_class_lookup(CustomLookup())
root = objectify.parse(fname,parser).getroot()
假设正在解析的文件是
<custom />
我希望这能打印“Made CustomElement”,但事实并非如此。我可以让它调用构造函数吗?
如何在不调用构造函数的情况下创建CustomElement类的实例?
>>> isinstance(root,CustomElement)
True
答案 0 :(得分:2)
来自lxml
docs:
元素初始化
前面有一件事需要了解。 元素类不能有
__init___
或__new__
方法。不应该有任何内部状态 要么,除了存储的数据 底层的XML树。元件 实例被创建和垃圾 在需要时收集,所以没有办法 预测代理的时间和频率 是为他们创造的。更糟糕的是,何时 调用__init__
方法, 对象甚至尚未初始化 表示XML标记,因此没有 在提供__init__
方面有很多用处 子类中的方法。大多数用例 不需要任何课程 初始化,所以你可以内容 你自己跳到下一个 部分暂时。但是,如果你 真的需要设置你的元素 关于实例化的类,有一个 可行的方法。 ElementBase 类具有
_init()
方法 可以被覆盖。它可以用来 修改XML树,例如构建 特殊的孩子或验证和更新 属性。
_init()
的语义 如下:
一次打电话 元素类实例化时间。那 是,当Python表示时 该元素由lxml创建。在 那个时候,元素对象是 完全初始化以代表一个 树中的特定XML元素。
该方法可以完全访问 XML树。修改可以在 与其他任何地方完全相同 在该计划中。
Python表示 可以创建多个元素 XML生命周期中的时间 底层C树中的元素。该 子类提供的
_init()
代码必须特别注意 多次执行也是 无害或被他们阻止 XML树中的某种标志。该 后者可以通过修改一个来实现 属性值或通过删除或 然后添加一个特定的子节点 在运行之前验证这一点 初始化过程。任何例外情况
_init()
中提出的将被传播 通过API调用导致 创建元素。所以要小心 用你在这里写的代码作为它 异常可能会出现各种情况 意想不到的地方。