I'm trying to inject an attribute into lxml.etree._Element
, but as that module is completely implemented in C, setattr
fails:
Traceback (most recent call last):
[...]
setattr(node.getroottree().getroot(), "attributeName", value)
AttributeError: 'lxml.etree._Element' object has no attribute 'attributeName'
The use case: I have a function that extracts text from a XML file by XPath and replaces $(ENV)
-like matches by the corresponding value. Therefore I don't want to have to pass the variables dictionary (e.g. {"ENV" : "replacement"}
to that function each time. Instead it would be easier to just have an attribute at a fixed place (XML root in my code). I could do a dumb workaround but injecting a Python attribute would be the best way. I cannot use a global variable because each XML file can have different variable values.
So, any way to inject something into C-based classes/objects?
You generally can't, as instances of C-defined types typically don't have per-instance
__dict__
entries to hold arbitrary attributes.A workaround for cases when a subclass or wrapper class won't work is to create a helper dictionary at the module level that maps the object you have to additional information. If the object you have isn't hashable, you can use
id(obj)
instead.So, for example, you could store a dictionary associated with the id of each root object: