Python:将属性注入到由C库创建的对象中

Python:将属性注入到由C库创建的对象中,python,lxml,code-injection,setattr,Python,Lxml,Code Injection,Setattr,我试图将一个属性注入lxml.etree.\u元素,但由于该模块完全用C实现,setattr失败: 用例:我有一个函数,它通过XPath从XML文件中提取文本,并用相应的值替换类似$ENV的匹配项。因此,我不希望每次都必须将变量字典(例如{ENV:replacement})传递给该函数。相反,在我的代码中,在XML根的固定位置有一个属性会更容易。我可以做一个愚蠢的变通方法,但注入Python属性将是最好的方法。我不能使用全局变量,因为每个XML文件可以有不同的变量值 那么,有什么方法可以将某些东

我试图将一个属性注入lxml.etree.\u元素,但由于该模块完全用C实现,setattr失败:

用例:我有一个函数,它通过XPath从XML文件中提取文本,并用相应的值替换类似$ENV的匹配项。因此,我不希望每次都必须将变量字典(例如{ENV:replacement})传递给该函数。相反,在我的代码中,在XML根的固定位置有一个属性会更容易。我可以做一个愚蠢的变通方法,但注入Python属性将是最好的方法。我不能使用全局变量,因为每个XML文件可以有不同的变量值


那么,有什么方法可以将某些东西注入到基于C的类/对象中呢?

通常不能,因为C定义类型的实例通常没有每个实例的dict条目来保存任意属性

当子类或包装类不起作用时,一种解决方法是在模块级创建一个帮助器字典,将您拥有的对象映射到其他信息。如果您拥有的对象不可散列,则可以使用idobj

例如,您可以存储一个与每个根对象的id关联的字典:

# Module level, setting up the data store
from collections import defaultdict
extra_info = defaultdict(dict) # Creates empty dicts for unknown keys

# Saving the info
root = node.getroottree().getroot()
extra_info[id(root)]["ENV"] = "replacement"

# Retrieving it later
root = node.getroottree().getroot()
info = extra_info[id(root)]

好吧,包装类将不起作用,因为node.getroottree.getroot仍将指向未包装的对象。我只有节点可用于我的功能;目前,我有一个变通方法node.getroottree.docinfo.URL=reprvariablesDict,因为我不需要XML URL,这是为数不多的可写属性之一,然后使用eval再次创建字典。好的,谢谢你的回答。你的变通方法也可以,但我想我还是保留我的方法,因为它会将变量与XML文档一起销毁。是的,如果你想让额外的信息与原始对象同时消失,你需要使用weakref.weakkeydictory来管理生命周期。
# Module level, setting up the data store
from collections import defaultdict
extra_info = defaultdict(dict) # Creates empty dicts for unknown keys

# Saving the info
root = node.getroottree().getroot()
extra_info[id(root)]["ENV"] = "replacement"

# Retrieving it later
root = node.getroottree().getroot()
info = extra_info[id(root)]