2011-02-24 116 views
1

我试图注入属性为lxml.etree._Element,但由于该模块是用C实现完全,setattr失败:的Python:属性注入到由C库创​​建的对象

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

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

因此,任何方式注入东西到基于C类/对象?

回答

-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)] 
+0

好,包裹类不会因为那时'node.getroottree()getroot工作() '仍然会指向未包装的对象。我只有'node'可用于我的功能;)目前,我有解决方法'node.getroottree()。​​docinfo.URL = repr(variablesDict)'(因为我不需要XML URL,那就是可写的几个属性之一),然后使用'eval'再次创建字典。 – AndiDog 2011-02-24 08:11:38

+0

为我的回答添加了一个更好的解决方法选项 – ncoghlan 2011-02-24 08:14:08

+0

好的谢谢你的答案。你的解决方法也会起作用,但我认为我会保留我的,因为它会与XML文档一起销毁变量。 – AndiDog 2011-02-24 16:16:14