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

时间:2011-02-24 07:36:47

标签: python lxml code-injection setattr

我正在尝试将一个属性注入lxml.etree._Element,但由于该模块完全在C中实现,setattr失败:

Traceback (most recent call last):
[...]
    setattr(node.getroottree().getroot(), "attributeName", value)
AttributeError: 'lxml.etree._Element' object has no attribute 'attributeName'

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

那么,是否可以将任何东西注入基于C的类/对象?

1 个答案:

答案 0 :(得分:-1)

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

子类或包装类不起作用的情况的解决方法是在模块级别创建一个帮助器字典,将您拥有的对象映射到其他信息。如果您拥有的对象不可清除,则可以使用id(obj)代替。

因此,例如,您可以存储与每个根对象的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)]