算是前幾周落下的博客補一篇。介紹一下python中如何解析配置文件。配置文件常用的幾種格式:xml,json,還有ini。其中ini算是最簡單的一種格式,因為小,解析的速度也要比xml和json快(並沒有科學的數據支撐,只是我個人想法)。當然,我並不是說xml和json不好,只是有時候只想在文件里寫點配置的話,還是ini比較小巧。好了廢話不多說,來講解一下python中處理ini配置文件的類ConfigPhaser。
一般來講,一個ini配置文件里,格式是醬嬸的:
[SectionA] # 方括號里叫做一個section a = aa # 這里的每一行,等號左側是一個option,右側是option的value b = bb c = cc [SectionB] optionint = 1 optionfloat = 1.1 optionstring = string
就這么簡單(配置文件是沒有注釋的,不要亂寫,否則讀的時候會出錯。xml和json也一樣)。
用python讀取配置文件的時候,也是非常簡單的:
1 with open(filename, 'r') as fr: 2 cfg = ConfigParser.ConfigParser() 3 cfg.readfp(fr)
這就讀好了。下面的工作就是解析cfg。
1 # 讀取所有sections: 2 secs = cfg.sections() # ['SectionA', 'SectionB']
結果得到section的列表。
1 # 讀取某一個section里面的所有options 2 ops0 = cfg.options(secs[0]) # ['a', 'b', 'c']
結果得到所有options的列表。
可是解析配置文件的目的並不是獲得option,而是獲得option和value的鍵值對呀!——直接使用items就好了:
1 ops1 = cfg.items(secs[1])
猜猜print ops1的時候會獲得什么?嗯,是的,你猜錯了。並不是一個字典,而是一個列表:
[('optionint', '1'), ('optionfloat', '1.1'), ('optionstring', 'string')]
希望把它當做字典來用的話,需要dict(ops1)
當我只想獲得某一個option的值怎么辦呢?不想一下子讀那么多數據的話,可以用一系列get的方法:
1 print cfg.getint(secs[1], 'optionint') # 1 2 print cfg.getfloat(secs[1], 'optionfloat') # 1.1 3 print cfg.get(secs[1], 'optionstring') # string
其實在類的內部實現中,getint和getfloat也只是在get上又封裝了一層。
這就是ConfigPhaser模塊的簡單用法。然而這個模塊並不只是能簡單的讀取配置文件,還可以動態的添加內容喲~醬嬸的:
1 cfg.add_section('SectionC') # 添加section 2 cfg.set('SectionC', 'ex', 'example') # 添加option及value
或者刪除配置:
1 cfg.remove_option('SectionC', 'ex') 2 cfg.remove_section('SectionC')
之后
1 with open(filename, 'w') as fw: 2 cfg.write(fw)
這樣就把配置寫回到配置文件里去了。要注意的是,讀取配置文件和寫配置文件最好分別進行,不要一個文件既讀又寫。首先,cfg讀取的時候用read,這就要求文件一定要用r/r+/a的方式讀才行,但是r不能寫,r+和a只能在結尾追加,這樣cfg在用write寫文件的時候,就會把原來的配置再寫到配置文件里去,而不是覆蓋方式。
大概就醬。so easy吧。不敢說完全弄清楚了這個配置文件類,但是基本用法這些大概就夠用了。
PS:配置文件的名字,可以不用ini做后綴。隨便什么都行,你高興就好。
2016.03.07更新:有同學反映ConfigPhaser不支持多線程讀寫。感覺多線程讀肯定沒問題,至於寫,本身寫文件就是一件需要很仔細的事,盡量還是不要多線程的好。只是,如果控制好同步,應該也可以的吧。誰有空的時候可以測試一下,我是不太想研究這個了。本來就是一個不願意踩坑的人,明知是雷區就應該盡量繞過去而不是蹚過去不是嗎?