最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(配置篇)
Python實戰(zhàn)社群
Java實戰(zhàn)社群
長按識別下方二維碼,按需求添加
掃碼關(guān)注添加客服
進Python社群▲
掃碼關(guān)注添加客服
進Java社群▲
作者丨星安果
來源丨AirPython
1.前言
在實際項目中,經(jīng)常會接觸到各種各樣的配置文件,它可以增強項目的可維護性
常用配件文件的處理方式,包含:JSON、ini / config、YAML、XML?等
本篇文章,我們將聊聊?Python 數(shù)據(jù)處理全家桶之配置文件大總結(jié)
2.JSON
Python 內(nèi)置了 JSON 模塊,可以非常方便操作 JSON 數(shù)據(jù)
常見的 4 個方法分別是:
json.load(json_file)
解析 JSON 文件,轉(zhuǎn)換為 Python 中對應(yīng)的數(shù)據(jù)類型
json.loads(json_string)
解析?JSON 格式的字符串,結(jié)果為 Python 中的字典
json.dump(python_content,file_path)
將 Python 數(shù)據(jù),包含:dict、list 寫入到文件中
json.dumps(python_dict)
將 Python 中 dict?轉(zhuǎn)為 JSON 格式的字符串
以下面這段 JSON 配置文件為例:
#config.json
{
??"mysql":?{
????"host":?"198.0.0.1",
????"port":?3306,
????"db":?"xh",
????"username":?"root",
????"password":?"123456",
????"desc":?"Mysql配置文件"
??}
}
1、讀取配置文件
讀取配置文件有兩種方式,分別是:
使用?json.load()?直接讀取配置文件
或者,先讀取配置文件中的內(nèi)容,然后使用?json.loads()?轉(zhuǎn)換為 Python 數(shù)據(jù)類型
需要指出的是,面對復(fù)雜層級的 JSON 配置文件,可以利用 jsonpath 進行讀??;jsonpath 類似于 xpath,可以通過正則表達式快速讀取數(shù)據(jù)
import?json
def?read_json_file(file_path):
????"""
????讀取json文件
????:param?file_path:
????:return:
????"""
????with?open(file_path,?'r',?encoding='utf-8')?as?file:
????????#?讀取方式二選一
????????#?方式一
????????result?=?json.load(file)
????????#?方式二
????????#?result?=?json.loads(file.read())
????????#?解析數(shù)據(jù)
????????host_mysql?=?result['mysql']['host']
????????port_mysql?=?result['mysql']['port']
????????db?=?result['mysql']['db']
????????print('Mysql地址:',?host_mysql,?",端口號:",?port_mysql,?",數(shù)據(jù)庫:",?db)
????return?result
2、保存配置文件
使用 json 中的?json.dump() 方法,可以將一個字典寫入到 JSON 文件中
def?write_content_to_json_file(output_file,?content):
????"""
????寫入到j(luò)son文件中
????:param?output_file:
????:param?content:
????:return:
????"""
????with?open(output_file,?'w')?as?file:
????????#?寫入到文件中
????????#?注意:為了保證中文能正常顯示,需要設(shè)置ensure_ascii=False
????????json.dump(content,?file,?ensure_ascii=False)
content_dict?=?{
????'mysql':?{
????????'host':?'127.0.0.1',
????????'port':?3306,
????????'db':?'xh',
????????'username':?'admin',
????????'password':?'123456',
????????'desc':?'Mysql數(shù)據(jù)庫'
????}
}
write_content_to_json_file('./output.json',?content_dict)
3、修改配置文件
如果需要修改配置文件,只需要先從配置文件中讀出內(nèi)容,然后修改內(nèi)容,最后將修改后的內(nèi)容保存的配置文件中即可
def?modify_json_file():
????"""
????修改json配置文件
????:return:
????"""
????result?=?read_json_file('./config.json')
????#?修改
????result['mysql']['host']?=?'198.0.0.1'
????write_content_to_json_file('./config.json',?result)3.ini/config
ini 配置文件和 config 配置文件的解析方式類似,僅僅是文件后綴不一致
這里我們以 ini 配置文件為例
#?config.ini
[mysql]
host?=?139.199.1.1
username?=?root
password?=?123456
port?=?3306
ini 文件由 3 部分組成,分別是:節(jié)點(Section)、鍵(Key)、值(Value)
常見的 Python 處理 ini 文件有兩種方式,包含:
使用內(nèi)置的 configparser 標準模塊
使用?configobj 第三方依賴庫
我們先來看看內(nèi)置的 configparser 模塊
3.1.1 讀取配置文件
實例化一個?ConfigParser 解析對象,使用 read() 方法讀取 ini 配置文件
from?configparser?import?ConfigParser
#?實例化解析對象
cfg?=?ConfigParser()
#?讀取ini文件內(nèi)容
cfg.read(file_path)
使用 sections() 函數(shù),可以獲取所有的節(jié)點列表
#?sections()?得到所有的section,并以列表的形式返回
sections?=?cfg.sections()
print(sections)
要獲取某一個節(jié)點下的所有鍵,可以使用 options(section_name) 函數(shù)
#?獲取某一個區(qū)域的所有key
#?cfg.options(section_name)
keys?=?cfg.options('mysql')
print(keys)
通過?items(section_name) 函數(shù),可以獲取某一個節(jié)點下的所有鍵值對
#?獲取某一個區(qū)域下的鍵值對
items?=?cfg.items("mysql")
print(items)
如果要獲取某一個節(jié)點下,某一個鍵下的值,使用 get(section_name,key_name)?函數(shù)即可
#?讀取某一個區(qū)域下的某一個鍵值
host?=?cfg.get("mysql",?"host")
print(host)3.1.2?寫入配置文件
和讀取配置文件類似,需要先實例化一個?ConfigParser 解析對象
首先,使用 add_section(section_name) 函數(shù)添加一個節(jié)點
#?加入節(jié)點和鍵值對
#?添加一個節(jié)點
cfg.add_section("redis")
然后,就可以使用 set(section_name,key,value) 函數(shù)往某一個節(jié)點添加鍵值對
#?往節(jié)點內(nèi),添加鍵值對
cfg.set("redis",?"host",?"127.0.0.1")
cfg.set("redis",?"port",?"12345")
最后,使用 write() 函數(shù)寫入到配置文件中去
#?寫入到文件中
cfg.write(open('./raw/output.ini',?'w'))3.1.3?修改配置文件
修改配置文件的步驟是,讀取配置文件,然后通過 set(section_name,key,value) 進行修改操作,最后使用 write() 函數(shù)寫入到文件中即可
def?modify_ini_file(file_path):
????"""
????修改ini文件
????:return:
????"""
????cfg.read(file_path)
????cfg.set("mysql",?"host",?"139.199.11.11")
????#?寫入
????cfg.write(open(file_path,?"w"))
接著,我們聊聊使用?configobj?操作 ini 配置文件的流程
首先安裝 configobj 依賴庫
#?依賴
#?pip3?install?configobj
3.2.1?讀取配置文件
直接將 ini 配置文件路徑作為參數(shù),使用?ConfigObj?類構(gòu)造一個對象
from?configobj?import?ConfigObj
#?實例化對象
config?=?ConfigObj(file_path,?encoding='UTF8')查看源碼可以發(fā)現(xiàn),ConfigObj 是 Section 節(jié)點的子類,而 Section 是 Dict 字典的子類

所以,可以直接通過鍵名 Key 獲取節(jié)點和鍵值
#?'configobj.ConfigObj'>
print(type(config))
#?'configobj.Section'>
print(type(config['mysql']))
#?節(jié)點
print(config['mysql'])
#?某一個鍵對應(yīng)的值
print(config['mysql']
3.2.2?修改配置文件
只需要讀取配置文件,然后直接修改 ConfigObj 對象,最后使用 write() 方法,即可以達到修改配置文件的目的
def?modify_ini_file(file_path):
????"""
????修改ini文件
????:param?file_path:
????:return:
????"""
????#?讀取配置文件
????config?=?read_ini_file(file_path)
????#?直接修改
????config['mysql']['host']?=?'139.199.1.1'
????#?刪除某個鍵值對
????try:
????????del?config['mysql']['db']
????except?Exception?as?e:
????????print('鍵不存在')
????????pass
????#?寫入
????config.write()3.2.3 寫入配置文件
寫入配置文件,首先需要實例化一個 ConfigObj 對象,傳入文件路徑
然后,設(shè)置節(jié)點、針對節(jié)點設(shè)置鍵值對
最后,調(diào)用 write() 方法,寫入到配置文件中
def?write_to_ini_file(output):
????"""
????寫入到ini文件中
????:param?output:
????:return:
????"""
????config?=?ConfigObj(output,?encoding='UTF8')
????config['website']?=?{}
????config['website']['url']?=?"www.baidu.com"
????config['website']['name']?=?"百度"
????#?保存
????config.write()4.YAML
Python 操作 YAML 文件,常見的 2 種方式分別是:pyyaml、ruamel.yaml
使用 pip 安裝依賴
#?安裝依賴
#?方式一
pip3?install?pyyaml
#?方式二
pip3?install?ruamel.yaml
下面以一個簡單的 YAML 配置文件為例,通過兩種方式進行說明
#?水果
Fruits:
??#?蘋果
??-?Apple:
??????name:?apple
??????price:??1
??????address:??廣東
??#?桔子
??-?Orange:
??????name:?orange
??????price:??3
??????address:??湖南
??#?香蕉
??-?Banana:
??????name:?banana
??????price:??2
??????address:??海南
我們先來看看 pyyaml
4.1.1 讀取配置文件
首先,讀取配置文件,使用 yaml.safe_load() 加載數(shù)據(jù),獲取的數(shù)據(jù)類型是字典
import?yaml
with?open(file_path,?"r")?as?file:
????data?=?file.read()
????#?safe_load()?讀取配置文件
????#?結(jié)果數(shù)據(jù)類型:dict
????result?=?yaml.safe_load(data)
????print(result)
接著,就可以通過 YAML 配置文件的層級關(guān)系,獲取鍵值
#?3、獲取yaml中的值
name?=?result['Fruits'][0]['Apple']['name']
price?=?result['Fruits'][0]['Apple']['price']
address?=?result['Fruits'][0]['Apple']['address']
print("名稱:",?name,?",price:",?price,?",address:",?address)
4.1.2?寫入配置文件
使用 YAML 中的 dump() 方法,可以將一個字典寫入到 YAML 配置文件中
需要注意的是,為了保證中文寫入能正常顯示,需要配置?allow_unicode=True
def?write_to_yaml_file(content,?file_path):
????"""
????寫入到y(tǒng)aml文件中
????:param?content:
????:param?file_path:
????:return:
????"""
????#?寫入到文件中
????with?open(file_path,?'w',?encoding='utf-8')?as?file:
????????yaml.dump(content,?file,?default_flow_style=False,?encoding='utf-8',?allow_unicode=True)
#?定義一個字典
content?=?{
???"websites":?[{"baidu":?{'url':?"www.baidu.com",?'name':?'百度',?"price":?100}},{"alibaba":?{'url':?"www.taobao.com",?'name':?'淘寶',?"price":?200}},{"tencent":?{'url':?"www.tencent.com",?'name':?'騰訊',?"price":?300}},]
}
write_to_yaml_file(content,?"./raw/new.yaml")4.1.3?修改配置文件
和修改 ini 文件類型,先讀取配置文件,然后修改字典中的內(nèi)容,最后使用上面的寫入方法,即可以達到修改配置文件的目的
def?modify_yaml_file():
????"""
????修改yaml文件
????:return:
????"""
????content?=?read_yaml_file('./raw/norm.yaml')
????print(content)
????#?修改dict
????content['Fruits'][0]['Apple']['price']?=?10086
????#?重新寫入到一個新的yaml文件中
????write_to_yaml_file(content,?'./raw/output.yaml')
接著,我們來聊聊使用 ruamel 操作 YAML 配置文件的流程
ruamel 是 pyyaml 的衍生版本,在傳統(tǒng) pyyaml 的基礎(chǔ)上,增加了 RoundTrip 模式,保證 YAML 配置文件的讀寫順序一致
所以,在讀取、修改、寫入方式上和 pyyaml 類似
4.2.1 讀取配置文件
from?ruamel?import?yaml
def?read_yaml_file(file_path):
????"""
????讀取yaml文件
????:param?file_path:
????:return:
????"""
????with?open(file_path,?'r',?encoding='utf-8')?as?file:
????????data?=?file.read()
????????#?解析yaml文件
????????#?類型:ordereddict
????????result?=?yaml.load(data,?Loader=yaml.RoundTripLoader)
????????name?=?result['Fruits'][0]['Apple']['name']
????????price?=?result['Fruits'][0]['Apple']['price']
????????address?=?result['Fruits'][0]['Apple']['address']
????????print("名稱:",?name,?",price:",?price,?",address:",?address)
????return?result
4.2.2?寫入配置文件
def?write_to_yaml_file(filepath,?data):
????"""
????寫入到y(tǒng)aml文件中
????:param?filepath:
????:param?data:
????:return:
????"""
????with?open(filepath,?'w',?encoding='utf-8')?as?file:
????????yaml.dump(data,?file,?Dumper=yaml.RoundTripDumper,?allow_unicode=True)
4.2.3?修改配置文件
def?modify_yaml_file():
????"""
????修改yaml文件
????:return:
????"""
????content?=?read_yaml_file('./raw/norm.yaml')
????print(content)
????#?修改dict
????content['Fruits'][0]['Apple']['price']?=?10086
????#?重新寫入到一個新的yaml文件中
????write_to_yaml_file('./raw/output.yaml',?content)5.XML
XML 作為一種標記語言,被用來設(shè)計存儲和傳輸數(shù)據(jù),很多項目經(jīng)常使用 XML 作為配置文件和數(shù)據(jù)傳輸類型
Python 內(nèi)置的 xml 模塊?可以很方便地處理 XML 配置文件
以下面這段配置文件為例:
<dbconfig>
????<mysql>
????????<host>127.0.0.1host>
????????<port>3306port>
????????<dbname>testdbname>
????????<username>rootusername>
????????<password>4355password>
????mysql>
dbconfig>
首先,使用 xml.dom.minidom.parser(file_path) 解析配置文件,利用?documentElement 屬性獲取 XML 根節(jié)點
import?xml.dom.minidom
#?讀取配置文件
dom?=?xml.dom.minidom.parse("./raw.xml")
#?利用?documentElement?屬性獲取?XML?根節(jié)點
#?根節(jié)點
root?=?dom.documentElement接著,使用?getElementsByTagName(tag_name) 方法,獲取某一節(jié)點
#?獲取mysql節(jié)點
node_mysql?=?root.getElementsByTagName('mysql')[0]
最后,使用?childNodes 屬性,遍歷節(jié)點的子 Node 節(jié)點,獲取節(jié)點的名稱和值
#?遍歷子節(jié)點,獲取名稱和值
for?node?in?node_mysql.childNodes:
????#?節(jié)點類型
????#?1:Element
????#?2:Attribute
????#?3:Text
????#?print(node.nodeType)
????if?node.nodeType?==?1:
????????print(node.nodeName,?node.firstChild.data)6.最后
到此,Python 數(shù)據(jù)全家桶以全部完結(jié)!


近期精彩內(nèi)容推薦:??


