簡體   English   中英

如何使一個類從lxml.objectify.Element繼承?

[英]How do I make a class inherit from lxml.objectify.Element?

我有一個用於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

事后看來,我建議不要使用lxml創建子類。

如評論所述, lxml.objectify.Element()不是類。 這是一個創建並返回對象的工廠方法 ,這意味着它不能被繼承。

盡管可以從ElementBaseObjectifiedElement繼承,但lxml文檔強烈警告您不得覆蓋__init____new__ ,這是我的原始答案所做的。

BIG FAT警告 :子類不得覆蓋__init____new__因為在創建或銷毀這些對象時絕對是未定義的。 元素的所有持久狀態都必須存儲在基礎XML中。 如果在創建后確實需要初始化對象,則可以實現_init(self)方法,該方法將在創建對象后直接調用。
lxml.etree.ElementBase文檔

我建議改為從其他類繼承。 如原始問題中所述,您可以很容易地從lxml.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)

使用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標記名稱。

正如Goyobruno desthuilliers指出的那樣, objectify.Element不是一個類,這意味着您不能從它繼承。 離開他們的評論后,我使用type()自己對此進行確認,並發現objectify.Element()返回了ObjectifiedElement類型的ObjectifiedElement

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

將我的類更改為從lxml.objectify.ObjectifiedElement繼承后,該類將按預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM