2011-08-15 82 views
2

我想構建一個樹結構來表示一個解析的配置文件(配置文件有一個層次結構)。我將其表示爲:Python的嵌套對象無法檢索函數中的值

class configContainer(): 

    treeDict = {} 
    instances = {} 

class configObject(): 

    def __init__(self, name, configLine, parent): 
     self.name = name    # Assign to the line number to make unique 
     self.parent = parent    
     self.children = [] 
     self.configLine = configLine # Actual line of the configuration 
     configContainer.instances[name] = self 

configContainer包含一組對象。 configContainer.instances使用「行號」鍵來映射到對象。 treeDict做了一個類似的映射,但使用不同的鍵(我在創建整個容器後創建了treeDict)。

然後我嘗試引用兩個不同的configContainers內的兩個對象。這從__main__工作正常。但是當我通過兩個configContainers的功能,情況總是從configContainer2

if __name__ == "__main__": 


    f1 = open('rfile', 'r') 
    configFile1 = f1.read() 
    f1.close() 

    configTree1 = parseConfig(configFile1) 
    configTree1.treeDict = createTreeDict(configTree1) 
    zObject1 = configTree1.instances["line10"] 


    f2 = open('sfile', 'r') 
    configFile2 = f2.read() 
    f2.close() 

    configTree2 = parseConfig(configFile2) 
    configTree2.treeDict = createTreeDict(configTree2) 
    zObject2 = configTree2.instances["line10"] 

    print "\n\nFrom __main__" 
    print "###########################" 
    print configTree1 
    print configTree2 
    print zObject1 
    print zObject2 


    compareConfigurations(configTree1, configTree2) 


def compareConfigurations(tmpTree1, tmpTree2): 

    print "\n\nFrom compareConfigurations" 
    print "###########################" 
    print tmpTree1 
    print tmpTree2 
    zObject1 = tmpTree1.instances["line10"] 
    zObject2 = tmpTree2.instances["line10"] 
    print zObject1 
    print zObject2 

結果返回的對象是:

### From __main__ 

<__main__.configContainer instance at 0xb77a34ec> 

<__main__.configContainer instance at 0xb740a68c> 

<__main__.configObject instance at 0xb740e3ac> 

<__main__.configObject instance at 0xb7414bcc> 


### From compareConfigurations 

<__main__.configContainer instance at 0xb77a34ec> 

<__main__.configContainer instance at 0xb740a68c> 

<__main__.configObject instance at 0xb7414bcc> 

<__main__.configObject instance at 0xb7414bcc> 

我想不通爲什麼我總是從找回的0xb7414bcc對象裏面compareConfigurations

+0

你覺得呢'類configContainer():'做,而不是'類configContainer:'或者'class configContainer(object):'?另請參閱[Python風格指南](http://www.python.org/dev/peps/pep-0008)。 – pillmuncher

回答

4

configContainer.instances是一個類屬性,所以如果你修改它的任何類的實例它將改變該類的所有實例。使用您當前的代碼,只要您使用相同的名稱創建新的configObject,它就會覆蓋該名稱的configContainer.instances中的條目。您應該使instances的實例屬性爲configContainer或確保您的configObjects具有不同的名稱。

class configContainer(): 
    def __init__(self): 
     self.instances = {} 
... 

這裏是正在發生的事情的一個簡單的例子:

>>> cc1 = configContainer() 
>>> cc2 = configContainer() 
>>> cc1.instances["line10"] = "foo" 
>>> configContainer.instances 
{'line10': 'foo'} 
>>> cc2.instances["line10"] = "bar" 
>>> configContainer.instances 
{'line10': 'bar'} 
>>> cc1.instances 
{'line10': 'bar'} 
+0

謝謝,這解決了我的問題。 –

1

parseConfigcreateTreeDict中的某些內容正在破壞您的instances字典。

請注意,在主你得到zObject1zObject2configTree1

zObject1 = configTree1.instances["line10"] 
#... 
zObject2 = configTree1.instances["line10"] 
# 
print zObject1 
print zObject2 

你說生產:

<__main__.configObject instance at 0xb740e3ac> 

<__main__.configObject instance at 0xb7414bcc> 

如果您發佈的源parseConfigcreateTreeDict我們可以得到到它的根源。

2

你知道,configContainer.instances不訪問實例變量,對不對?

如果要參照包裝類,你將不得不做這樣的事情:

class configContainer(object): 
    treeDict = {} 
    instances = {} 

    def configObject(self, name, configLine, parent): 
     return _configObject(self, name, configLine, parent) 

    class _configObject(object): 
     def __init__(self, container, name, configLine, parent): 
      self.name = name    # Assign to the line number to make unique 
      self.parent = parent    
      self.children = [] 
      self.configLine = configLine # Actual line of the configuration 
      container.instances[name] = self