I'm trying to extend xml.ElementTree.Element
. The problem is that the constructor gives me a ready made Element
instance which I cannot extend without tampering with the source code of xml
.
Is there a way to initialize a class that inherits from Element and copy the whole Element attributes into the SubClass?
import xml.ElementTree as ET
root = ET.parse('file.xml').getroot() # retrieves Element instance
class ExtendedElement(ET.Element):
def __init__(self, element):
pass
# somehow initialize the ExtendedElement instance
# with all methods and attributes of element
# without copying each attribute individually
# ie self.attrib = element.attrib
def custom_method(self):
print(self.attrib)
ext = ExtendedElement(root)
ext.custom_method()
assert root.attrib == ext.attrib
assert list(ext) == list(root)
Usually I would just go on and call self.__dict__.update(element.__dict__)
, however Element
doesn't seem to have a __dict__
(how is this even possible?).
I want to avoid copying all attributes individually as I might miss some hidden ones without knowing.
As @CristiFati suggested in the comments, you should use composition here.
class ExtendedElement:
def __init__(self, element):
self.element = element
def custom_method(self):
print(self.element.attrib)
ext = ExtendedElement(root)
ext.custom_method()
Then the 2 assertions will work with the correct alternation:
assert root.attrib == ext.element.attrib
assert list(ext.element) == list(root)
If you really need list(ext)
to work then you can implement __iter__
:
def __iter__(self):
return iter(self.element)
then the second assertion will work as is:
assert list(ext) == list(root)
Depending on your needs, you can hack ExtendedElement
to expose all the attributes that element
has by implementing __getattr__
:
def __getattr__(self, name):
return getattr(self.element, name)
then
ext = ExtendedElement(root)
print(ext.attrib)
will output (with my test.xml):
{'b': '1'}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.