2010-07-10 84 views
17

通常情況下,我的代碼在一個變量中獲取特定的項目如下如下閱讀的ini文件中的所有內容複製到字典與Python

try: 
    config = ConfigParser.ConfigParser() 
    config.read(self.iniPathName) 
except ConfigParser.MissingSectionHeaderError, e: 
    raise WrongIniFormatError(`e`) 

try: 
    self.makeDB = config.get("DB","makeDB") 
except ConfigParser.NoOptionError: 
    self.makeDB = 0 

有沒有辦法讀取一個python字典中的所有內容?

例如

 
[A] 
x=1 
y=2 
z=3 
[B] 
x=1 
y=2 
z=3 

寫入

 
val["A"]["x"] = 1 
... 
val["B"]["z"] = 3 

回答

26

我建議子類ConfigParser.ConfigParser(或SafeConfigParser,& C)安全地訪問「保護」屬性(名稱以單下劃線 - 「私人」將名稱以2個下劃線,不被訪問,即使在子類...):

import ConfigParser 

class MyParser(ConfigParser.ConfigParser): 

    def as_dict(self): 
     d = dict(self._sections) 
     for k in d: 
      d[k] = dict(self._defaults, **d[k]) 
      d[k].pop('__name__', None) 
     return d 

這模擬配置解析器通常的邏輯,並保證在Python的所有版本的工作,其中有一個ConfigParser.py模塊(高達2.7,這是最後的2.*系列 - 知道不會有未來的Python 2.any版本是如何兼容的bability可以是保證 ;-)。

如果需要,以支持未來的Python 3.*版本(最高可達3.1,可能不久即將到來的3.2應該是很好,只是重命名模塊全部小寫configparser而不是過程),可能需要一些注意/調整數幾年後,但我不會期望任何重大事件。

23

我設法得到一個答案,但我相信應該有一個更好的。

dictionary = {} 
for section in config.sections(): 
    dictionary[section] = {} 
    for option in config.options(section): 
     dictionary[section][option] = config.get(section, option) 
+2

我覺得這是一個很好的解決方案,你爲什麼不快樂呢? – 2010-07-10 20:52:21

+2

這應該是答案,因爲它解決了問題,而不必使用「私有」「_sections」屬性。當然,如果需要使用OrderedDict,只需使用它來代替常規字典。 – SizzlingVortex 2015-10-14 16:25:13

+1

用'defaultdict(dict)'代替'dictionary'會刪除中間字典的創建。 – noxdafox 2016-03-03 11:29:32

10

ConfigParser的實例數據在內部存儲爲嵌套字典。您可以複製它,而不是重新創建它。

>>> import ConfigParser 
>>> p = ConfigParser.ConfigParser() 
>>> p.read("sample_config.ini") 
['sample_config.ini'] 
>>> p.__dict__ 
{'_defaults': {}, '_sections': {'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B':   {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}}, '_dict': <type 'dict'>} 
>>> d = p.__dict__['_sections'].copy() 
>>> d 
{'A': {'y': '2', '__name__': 'A', 'z': '3', 'x': '1'}, 'B': {'y': '2', '__name__': 'B', 'z': '3', 'x': '1'}} 

編輯:

亞歷克斯·馬爾泰利的solution是更清潔,更健壯,更漂亮。雖然這是公認的答案,但我建議使用他的方法。查看他對此解決方案的評論以獲取更多信息。

+4

我總是不願意訪問屬性的protected(「以下劃線開頭」)(並且通過'__dict__'的荒謬複雜並不能幫助 - 'd = p._sections.copy() '完全相同,更簡單,更直接)。這就是爲什麼我在回答中建議使用子類的替代方法 - 子類是_expected_來訪問基類的受保護屬性。在C++中,這是強制執行的;在Python中,它並不是,但那是因爲用戶應該受到嚴格的紀律處理以不需要執行;-)。 – 2010-07-11 00:14:51

1

如何在py中解析ini文件?

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.read('/var/tmp/test.ini') 
print config.get('DEFAULT', 'network') 

凡test.ini文件包含:

[DEFAULT] 
network=shutup 
others=talk 
6

我知道,這個問題在5年前問過,但今天我做了這個字典理解啄:

parser = ConfigParser() 
parser.read(filename) 
confdict = {section: dict(parser.items(section)) for section in parser.sections()} 
0

還有一件事要注意,ConfigParser將鍵值轉換爲小寫,因此,如果您將配置條目轉換爲字典,請交叉檢查您的要求。因此我面臨一個問題。對於我來說,我有駱駝式的鑰匙,因此,當我開始使用字典而不是文件時,必須更改一些代碼。ConfigParser.get()方法在內部將密鑰轉換爲小寫。

-1

https://wiki.python.org/moin/ConfigParserExamples

def ConfigSectionMap(section): 
dict1 = {} 
options = Config.options(section) 
for option in options: 
    try: 
     dict1[option] = Config.get(section, option) 
     if dict1[option] == -1: 
      DebugPrint("skip: %s" % option) 
    except: 
     print("exception on %s!" % option) 
     dict1[option] = None 
return dict1