2011-02-24 117 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