Python實(shí)現(xiàn)解析ini配置文件的示例詳解
楔子
在開發(fā)過程中,配置文件是少不了的,只不過我們有時(shí)會(huì)將 py 文件作為配置文件(config.py),然后在其它的模塊中直接導(dǎo)入。這樣做是一個(gè)好主意,不過配置文件是有專門的格式的,比如:ini, yaml, toml 等等。
而對(duì)于 Python 而言,也都有相應(yīng)的庫來解析相應(yīng)格式的文件,下面我們來看看 ini 文件要如何解析。
ini 文件
先來了解一下 ini 文件的格式:
[satori] name?=?古明地覺 age?=?16 where?=?東方地靈殿 [koishi] name?=?古明地戀 age?=?15 where?=?東方地靈殿 [marisa] name?=?霧雨魔理沙 age?=?17 where?=?魔法森林
; 以分號(hào)或井號(hào)開頭表示注釋,不影響
ini 文件總分可以分為三塊,分別是:
- section:就是寫在 [] 里面的內(nèi)容,可以把它理解為一個(gè)段;
- parameter:以 key = value 的形式出現(xiàn),比如 age = 16,那么 age 就是 key、16 就是 value,注意:每個(gè) section 都有自己的 parameter;
- 注釋:以分號(hào)開頭,無影響,會(huì)被忽略掉。
可以看到結(jié)構(gòu)還是比較清晰的,那么 Python 要如何解析呢?Python 解析 ini 文件需要使用一個(gè)名叫 configparser 的庫,這個(gè)庫是自帶的,我們可以直接用。
import?configparser #?實(shí)例化一個(gè)?ConfigParser?實(shí)例 config?=?configparser.ConfigParser() #?打開?ini?文件 config.read("cfg.ini",?encoding="utf-8") #?獲取所有的?section print(config.sections()) """ ['satori',?'koishi',?'marisa'] """ #?獲取某一個(gè)?section?的所有?parameter print(config["satori"]) """ <Section:?satori> """ #?我們可以像操作字典一樣操作?parameter print(list(config["satori"])) """ ['name',?'age',?'where'] """ print(list(config["satori"].values())) """ ['古明地覺',?'16',?'東方地靈殿'] """ print(list(config["satori"].items())) """ [('name',?'古明地覺'),?('age',?'16'),?('where',?'東方地靈殿')] """ #?獲取某個(gè)?key?對(duì)應(yīng)的?value #?如果?key?不存在則拋出?KeyError print(config["marisa"]["where"]) """ 魔法森林 """ #?也可以調(diào)用?get?方法 #?在?key?不存在時(shí),指定一個(gè)默認(rèn)值 print(config["marisa"].get("age")) """ 17 """ #?我們發(fā)現(xiàn)?age?居然是一個(gè)字符串 #?因?yàn)槟J(rèn)解析得到的都是字符串 print(config["marisa"]["age"].__class__) """ <class?'str'> """ #?可以通過?getint?獲取 #?會(huì)將?value?轉(zhuǎn)成整型,但轉(zhuǎn)化失敗的話會(huì)報(bào)錯(cuò) #?除了?getint?之外,還有?getfloat、getboolean print(config["marisa"].getint("age")?==?17) """ True """ #?最后也可以直接轉(zhuǎn)成字典 print(dict(config["koishi"])) """ {'name':?'古明地戀',?'age':?'15',?'where':?'東方地靈殿'} """ print(dict(config)) """ {'DEFAULT':?<Section:?DEFAULT>,? ?'satori':?<Section:?satori>,? ?'koishi':?<Section:?koishi>,? ?'marisa':?<Section:?marisa>} """ print({k:?dict(v)?for?k,?v?in?config.items()}) """ {'DEFAULT':?{},? ?'satori':?{'name':?'古明地覺',? ????????????'age':?'16',? ????????????'where':?'東方地靈殿'},? ?'koishi':?{'name':?'古明地戀',? ????????????'age':?'15',? ????????????'where':?'東方地靈殿'},? ?'marisa':?{'name':?'霧雨魔理沙',? ????????????'age':?'17',? ????????????'where':?'魔法森林'}} """
可以看到還是比較容易的,因?yàn)?ini 這種文件格式本身就很簡單。除了讀取文件,我們還可以進(jìn)行寫入。
import?configparser #?實(shí)例化一個(gè)?ConfigParser?類的實(shí)例 config?=?configparser.ConfigParser() config["basic"]?=?{"Host":?"127.0.0.1", ???????????????????"Port":?"8888", ???????????????????"Username":?"satori"} config["thread"]?=?{} config["thread"]["name"]?=?"my_thread" config["thread"]["num"]?=?"3" with?open("cfg.ini",?"w",?encoding="utf-8")?as?f: ????config.write(f)
雖然成功寫入了,但是我們看到結(jié)果變成了小寫。是的,對(duì)于 parameter 來說,無論是大寫還是小寫,寫入文件的時(shí)候都會(huì)變成小寫。然后讀取也是,無論 ini 文件中是大寫還是小寫,讀取之后都會(huì)變成小寫。
注意:大小寫不敏感只是針對(duì)于 parameter,對(duì)于 section 來說還是區(qū)分大小寫的。
特殊格式
我們上面配置的 parameter 中的 key, value 都是一個(gè)普通的單詞,但其實(shí)我們還可以配置的更加復(fù)雜一些。
我們操作一波,看看能否正常解析。
import?configparser #?實(shí)例化一個(gè)?ConfigParser?實(shí)例 config?=?configparser.ConfigParser() #?打開?ini?文件 config.read("cfg.ini",?encoding="utf-8") print(dict(config["簡單值"])) """ {'鍵':?'值',? ?'鍵?里面?有空格':?'合法',? ?'值?里面?有空格':?'也?合?法',? ?'等號(hào)?周圍?有?空格':?'仍然合法',? ?'你也使用':?'代替等號(hào)'} """ print(dict(config["所有值都是字符串"])) """ {'這是字符串':?'123',? ?'這也是字符串':?'3.14',? ?'整數(shù)、浮點(diǎn)數(shù)、布爾值都是字符串':?'true'} """ #?true?True?yes?都可以轉(zhuǎn)成布爾值?True #?false?False?no?都可以轉(zhuǎn)成布爾值?False print(config["所有值都是字符串"].getboolean( ????'整數(shù)、浮點(diǎn)數(shù)、布爾值都是字符串')) """ True """ print(dict(config["值占多行"])) """ {'洪世賢':?'你怎么穿品如的衣服啊\n還用人東西'} """ print(dict(config["值為空字符串"])) """ {'key1':?'',?'key2':?''} """
結(jié)果是正常的,但是很明顯上面這種做法有點(diǎn)閑的沒事了,以后就統(tǒng)一寫成 key = value 的形式即可。另外如果 ini 文件中只有 key 沒有 value 的話,默認(rèn)是報(bào)錯(cuò)的,但可以通過一個(gè)參數(shù)改變這一點(diǎn):
import?configparser #?"key?="?這種形式不叫沒有值,它是有值的,值為空字符串 #?"key"?這種形式才是沒有值,解析的時(shí)候默認(rèn)會(huì)報(bào)錯(cuò) #?可以通過一個(gè)參數(shù)改變這一點(diǎn) config?=?configparser.ConfigParser(allow_no_value=True) config.read_string( ????""" [mysqld] user?=?mysql skip-bdb """) print(dict(config["mysqld"])) """ {'user':?'mysql',?'skip-bdb':?None} """
除此之外,name 之間還可以發(fā)生引用。
import?configparser config?=?configparser.ConfigParser() #?可以通過?%(key)s?的方式對(duì)同一個(gè)?section?中的其它?key?進(jìn)行引用 #?所以如果想表示一個(gè)?%?的話,需要寫兩個(gè)?%,因?yàn)樯婕暗睫D(zhuǎn)義 config.read_string(""" [section1] user?=?古明地覺 age?=?16 info?=?%(user)s--%(age)s? percent?=?80%%? """) print(dict(config["section1"])) """ {'user':?'古明地覺',?'age':?'16',? ?'info':?'古明地覺--16',?'percent':?'80%'} """
還是很簡單的,如果想引用其它的 section 中的 name 要怎么做呢?
import?configparser #?指定該參數(shù)之后,我們就不能通過?%(name)s?的方式引用了 #?需要使用?${name}?這種格式,顯然更方便了 config?=?configparser.ConfigParser( ????interpolation=configparser.ExtendedInterpolation() ) config.read_string(""" [DEFAULT] 默認(rèn)的?=?自動(dòng)加入到每一個(gè)?section?中 [section1] user?=?古明地覺 age?=?16 info?=?${user}?--?${age}? [section2] info?=?${section1:user},?${section1:age} """) print(dict(config["section1"])) """ {'user':?'古明地覺',? ?'age':?'16',? ?'info':?'古明地覺?--?16',? ?'默認(rèn)的':?'自動(dòng)加入到每一個(gè)?section?中'} """ print(dict(config["section2"])) """ {'info':?'古明地覺,?16',? ?'默認(rèn)的':?'自動(dòng)加入到每一個(gè)?section?中'} """
小結(jié)
以上就是 ini 文件的一些簡單用法,以后我們?cè)趯懪渲玫臅r(shí)候,不妨使用一些專門用來表示配置的文件格式,不一定非要寫在 py 文件里面。
而且使用 ini 等配置文件的一個(gè)好處就是,即便不懂 Python 的人也能看懂;或者這個(gè)配置文件不一定是要由你來寫,可能是別人寫,而那個(gè)人不用 Python,但是通過 ini 文件的話就省去了溝通的成本。
后續(xù)我們繼續(xù)介紹其它種類的配置文件,比如 yaml, toml,因?yàn)?ini 雖然簡單,但表達(dá)能力還是很有限的。而 yaml 和 toml 的表達(dá)能力要更豐富,應(yīng)用領(lǐng)域也要更廣一些。
以上就是Python實(shí)現(xiàn)解析ini配置文件的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Python解析ini配置文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python二叉樹的遍歷操作示例【前序遍歷,中序遍歷,后序遍歷,層序遍歷】
這篇文章主要介紹了Python二叉樹的遍歷操作,結(jié)合實(shí)例形式分析了Python針對(duì)二叉樹的前序遍歷,中序遍歷,后序遍歷,層序遍歷等相關(guān)操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-12-12PyQt5結(jié)合matplotlib繪圖的實(shí)現(xiàn)示例
這篇文章主要介紹了PyQt5結(jié)合matplotlib繪圖的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Python如何統(tǒng)計(jì)大小寫字母個(gè)數(shù)和數(shù)字個(gè)數(shù)
這篇文章主要介紹了Python如何統(tǒng)計(jì)大小寫字母個(gè)數(shù)和數(shù)字個(gè)數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Python函數(shù)中的函數(shù)(閉包)用法實(shí)例
這篇文章主要介紹了Python函數(shù)中的函數(shù)(閉包)用法,結(jié)合實(shí)例形式分析了Python閉包的定義與使用技巧,需要的朋友可以參考下2016-03-03python wav模塊獲取采樣率 采樣點(diǎn)聲道量化位數(shù)(實(shí)例代碼)
這篇文章主要介紹了python wav模塊獲取采樣率 采樣點(diǎn)聲道量化位數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01python教程之用py2exe將PY文件轉(zhuǎn)成EXE文件
py2exe是一個(gè)將python腳本轉(zhuǎn)換成windows上的可獨(dú)立執(zhí)行的可執(zhí)行程序(*.exe)的工具,這樣,你就可以不用裝python而在windows系統(tǒng)上運(yùn)行這個(gè)可執(zhí)行程序。2014-06-06