如何使类继承自lxml.objectify.Element?

时间:2018-03-19 15:17:37

标签: python inheritance lxml lxml.objectify

我有一个Person对象的Python类,它继承了xml.etree.ElementTree.Element

from xml.etree import ElementTree
class Person(ElementTree.Element):
    def __init__(self, name, age):
        super().__init__("person", name=name, age=str(age))

person = Person("Paul", 23)

我计划扩展我的Person类以包含其他属性和子标记。在此之前,我想通过将我的类转换为使用lxml.objectify.Element来简化属性访问。

from lxml import objectify
class Person(objectify.Element):
    def __init__(self, name, age):
        super().__init__("person", name=name, age=str(age))

person = Person("Paul", 23)

不幸的是,尝试从objectify.Element继承会引发关于创建cython_function_or_method个实例的TypeError。

Traceback (most recent call last):
  File "C:/Users/svascellar/.PyCharmCE2017.3/config/scratches/scratch_1.py", line 2, in <module>
    class Person(objectify.Element):
TypeError: cannot create 'cython_function_or_method' instances

为什么我的班级会引发TypeError?如何继承frrom lxml.objectify.Element

1 个答案:

答案 0 :(得分:2)

事后看来,我建议使用lxml 反对来创建子类。

正如提到的评论,lxml.objectify.Element()不是一个类。 <{3}}创建并返回一个对象,意味着它不能被继承。

虽然可以从factory methodElementBase继承,但lxml文档强烈警告您不能覆盖我原来的__init____new__回答了。

  

BIG FAT WARNING :子类不能覆盖__init____new__,因为在创建或销毁这些对象时,它们是绝对未定义的。元素的所有持久状态必须存储在基础XML中。如果确实需要在创建后初始化对象,则可以实现一个_init(self)方法,该方法将在创建对象后直接调用。
   - ObjectifiedElement

我建议继承一个不同的类。正如原始问题中所提到的,您可以非常轻松地从Documentation for lxml.etree.ElementBase继承。

from xml.etree import ElementTree
class Person(ElementTree.Element):
    def __init__(self, name, age):
        super().__init__("person", name=name, age=str(age))

person = Person("Paul", 23)

使用lxml的子类可能比它的价值更麻烦。但是,如果确实想要在lxml下继承警告,那么您可以在下面看到我的原始答案。

旧答案(不安全)

尝试继承lxml.objectify.ObjectifiedElement

from lxml import objectify
class person(objectify.ObjectifiedElement):
    def __init__(self, name, age):
        super().__init__(name=name, age=str(age))

my_person = person("Paul", 23)
print(etree.tostring(my_person, encoding="unicode"))
# output: <person age="23" name="Paul"/>

确保您的类名与XML标记匹配,因为ObjectifiedElement使用根XML标记名称的类名。

由于lxml.etree.ElementTree.ElementGoyo指出,objectify.Element不是一个类,这意味着您无法继承它。在发表评论时,我使用type()为自己确认了这一点,并发现objectify.Element()返回了ObjectifiedElement类型的对象。

from lxml import objectify
person = objectify.Element("person", name="Paul", age="23")
print(type(person))
# output: <class 'lxml.objectify.ObjectifiedElement'>

将我的课程改为继承自lxml.objectify.ObjectifiedElement后,该课程按预期工作。