lxml objectify不会为自定义元素类调用构造函数

时间:2010-12-21 13:00:51

标签: python constructor lxml objectify

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

1 个答案:

答案 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调用导致   创建元素。所以要小心   用你在这里写的代码作为它   异常可能会出现各种情况   意想不到的地方。

  •