In hindsight, I recommend against using lxml
to create subclasses.
As the comments mentioned, lxml.objectify.Element()
is not a class. It is a factory method that creates and returns an object, meaning it cannot be inherited.
While it's possible to inherit from ElementBase
or ObjectifiedElement
, the lxml documentation strongly warns that you must not override __init__
or __new__
, which my original answer did.
BIG FAT WARNING: Subclasses must not override __init__
or __new__
as it is absolutely undefined when these objects will be created or destroyed. All persistent state of Elements must be stored in the underlying XML. If you really need to initialize the object after creation, you can implement an _init(self) method that will be called directly after object creation.
- Documentation for lxml.etree.ElementBase
I suggest inheriting from a different class instead. As mentioned in the original question, you can inherit from lxml.etree.ElementTree.Element
fairly easily.
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)
Working with sub-classes of lxml
may be more trouble than it's worth. However, if you really want to subclass lxml
despite the warnings, you can see my original answer below.
Old Answer (Unsafe)
Try inheriting from lxml.objectify.ObjectifiedElement
instead.
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"/>
Make sure that your class name matches your XML tag, as ObjectifiedElement
uses the class name for the root XML tag name.
As Goyo and bruno desthuilliers pointed out, objectify.Element
is not a class, which means you can't inherit from it. Going off their comments, I used type()
to confirm this for myself and discovered that objectify.Element()
returned an object of type ObjectifiedElement
.
from lxml import objectify
person = objectify.Element("person", name="Paul", age="23")
print(type(person))
# output: <class 'lxml.objectify.ObjectifiedElement'>
After changing my class to inherit from lxml.objectify.ObjectifiedElement
, the class worked as expected.