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

发布于 2024-10-08 11:39:22 字数 828 浏览 5 评论 0原文

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

lxml.objectify does not seem to call the constructors for my custom element classes:

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()

Suppose the file being parsed is

<custom />

I would like this to print "Made CustomElement", but it does not. Can I make it call the constructor?

How is it possible for an instance of the CustomElement class to be created without the constructor being called?

>>> isinstance(root,CustomElement)
True

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

友谊不毕业 2024-10-15 11:39:22

来自 lxml 文档

元素初始化

首先需要了解一件事。
元素类不得有
__init_____new__ 方法。不应该有任何内部状态
要么,除了存储在
底层的 XML 树。元素
实例被创建并且垃圾
需要时收集,所以没办法
预测代理的时间和频率
是为他们创造的。更糟糕的是,当
调用 __init__ 方法,
对象甚至还没有初始化
代表XML标签,所以没有
在提供 __init__ 方面有很大用处
子类中的方法。

大多数用例
不需要任何课程
初始化,这样你就可以内容
自己跳到下一个
暂时。但是,如果您
确实需要设置你的元素
实例化类,有一个
可能的方式来做到这一点。元素库
类有一个 _init() 方法
可以被覆盖。它可以用来
修改XML树,例如构造
特殊儿童或核实并更新
属性。

_init() 的语义
具体如下:

  • 调用一次
    元素类实例化时间。那
    是,当 Python 表示为
    该元素由 lxml 创建。在
    此时,元素对象是
    完全初始化以表示
    树中的特定 XML 元素。

  • 该方法可以完全访问
    XML 树。修改可以在
    与其他地方完全相同的方式
    在程序中。

  • Python 表示
    的元素可以被创建多个
    XML 生命周期内的次数
    底层 C 树中的元素。这
    子类提供的 _init() 代码本身必须特别注意
    多次执行要么是
    无害或可以通过以下方式防止它们
    XML 树中的某种标志。这
    后者可以通过修改来实现
    属性值或通过删除或
    添加特定的子节点,然后
    在运行之前验证这一点
    init 进程。

  • 任何例外情况
    _init() 中引发的将被传播
    通过API调用导致
    元素的创建。所以要小心
    用你在这里写的代码作为它的
    异常情况可能会出现在各种情况
    意想不到的地方。

From the lxml docs:

Element initialization

There is one thing to know up front.
Element classes must not have an
__init___ or __new__ method. There should not be any internal state
either, except for the data stored in
the underlying XML tree. Element
instances are created and garbage
collected at need, so there is no way
to predict when and how often a proxy
is created for them. Even worse, when
the __init__ method is called, the
object is not even initialized yet to
represent the XML tag, so there is not
much use in providing an __init__
method in subclasses.

Most use cases
will not require any class
initialisation, so you can content
yourself with skipping to the next
section for now. However, if you
really need to set up your element
class on instantiation, there is one
possible way to do so. ElementBase
classes have an _init() method that
can be overridden. It can be used to
modify the XML tree, e.g. to construct
special children or verify and update
attributes.

The semantics of _init()
are as follows:

  • It is called once on
    Element class instantiation time. That
    is, when a Python representation of
    the element is created by lxml. At
    that time, the element object is
    completely initialized to represent a
    specific XML element within the tree.

  • The method has complete access to the
    XML tree. Modifications can be done in
    exactly the same way as anywhere else
    in the program.

  • Python representations
    of elements may be created multiple
    times during the lifetime of an XML
    element in the underlying C tree. The
    _init() code provided by subclasses must take special care by itself that
    multiple executions either are
    harmless or that they are prevented by
    some kind of flag in the XML tree. The
    latter can be achieved by modifying an
    attribute value or by removing or
    adding a specific child node and then
    verifying this before running through
    the init process.

  • Any exceptions
    raised in _init() will be propagated
    throught the API call that lead to the
    creation of the Element. So be careful
    with the code you write here as its
    exceptions may turn up in various
    unexpected places.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文