1. 程式人生 > 實用技巧 >python讀寫配置檔案使用總結與避坑指南---轉載

python讀寫配置檔案使用總結與避坑指南---轉載

【小宅按】最近拿python在寫專案部署的相關整合程式碼,本來兩天的工作量,硬是在來回的需求變更中,拖到了一週的時間。今天算是暫時告一段落了。這次由於涉及多個系統的呼叫和配置引數,程式碼開發中出現了較多之前未發現或者說沒暴露出來的問題,今天針對這些知識點進行相關的複習與總結

Python 配置檔案管理

configparser是python推薦使用的配置檔案管理模組,但坦白說它真的不怎麼好用,使用yaml、json等格式的儲存,在多層級資料儲存上,效率要比它高很多。但存在即合理,不是所有人都會使用yaml的格式,至於json的格式,很容易導致確實括號等問題,最終json.loads時報錯....

關於命名:
python2中模組叫:ConfigParser
python3中更名為:configparser
eg:其實有時候懶得寫2和3的差別,但很多公司或者團隊至今還在使用python2,然後一匯入報錯,就說是我的內容寫的有問題,心累....
先來看看它的基本使用:
我們首先的定義一個配置檔案:

  1. 配置檔案分為
  • section 使用方括號包裹的名稱,區分大小寫
  • option 你可以理解為變數名稱,option及其對應的值,不區分大小寫
  • 配置檔案中的鍵值對可以使用=或者:進行連線,但推薦使用=,為什麼?因為=不會出現中文符號的異常問題!比如下面的報錯:
    configparser.ParsingError: Source contains parsing errors: 'config.ini'
  • 鍵值對的分隔符及行首、行尾的空格會被strip()掉
  • 關於DEFAULT,這個section幾乎在每個配置檔案中都會出現
  • DEFAULT不會再conf.section()中顯示
  • 它類似於python的繼承,預設子section都會具備DEFAULT的內容。當子section中出現與DEFAULT同名的鍵,會覆蓋DEFAULT的原始內容
  • key:value中value可以存在多行,比如例子中的version,但換行後的內容,切記不可定格寫,不然會被認為是key,而導致報錯。
  • 配置檔案中的value不管是int還是str亦或者表面看起來的列表[1,2,3]或者字典樣式{"name":"Urnaus"}都會被認為是str字串型別。所以配置檔案中,切記不要使用列表的樣式,推薦使用json格式,這樣可以通過json模組進行字典的轉換
  • 配置檔案支援%(key)s的變數解析能力,些許的類似python....

說完了配置檔案,再來說說怎麼讀取配置檔案吧:

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @JianShu  : 清風Python
# @Date     : 2019/6/8 22:30
# @Software : PyCharm
# @version  :Python 3.6.8
# @File     : PythonConfig.py
import configparser

# 初始化
conf = configparser.ConfigParser()
# 讀取配置檔案
conf.read('config.ini', encoding='utf-8')



# 獲得配置檔案中的所有sections
print(conf.sections())
# section是區分大小寫的,寫成小寫會被認為不存在
print(conf.has_section('mysql'))



# 獲取section = Mysql 下的所有options,即keys
print(conf.options('Mysql'))
# option 不區分大小寫,判斷結果為True
print(conf.has_option('Mysql', 'DATABASE'))



# 獲取section = Mysql 下的所有鍵值對
print(conf.items('Mysql'))



# 獲取section=Mysql下host鍵對應的value值
# get方法通過不同型別,存在getint、getfloat、getboolean 不同的型別
# 其中getboolean 可以識別 true/false、 1/0、yes/no、 on/off
print(conf.get('Mysql', 'host'))
print(conf.getboolean('Mysql', 'status'))
print(conf.get('Mysql', 'uri'))



# 刪除鍵值對,同樣的還設有remove_section(section)就不演示了...
# conf.remove_section('Mysql')
conf.remove_option('Mysql', 'status')


# 我們添加了section為Python,並建立了tools=Pycharm
# 列印顯示正常,但是配置檔案中,並沒有
conf.add_section('Python')
conf.set("Python", "tools", "Pycharm")
print(conf.get("Python", "tools"))
# 此時的配置儲存在記憶體中,需要寫入檔案方可生效
with open("config.ini", "w+") as f:
    conf.write(f)

output:
['Mysql']

False

['creator', 'host', 'port', 'user', 'password', 'database', 'status', 'uri', 'path', 'version', 'author', 'number']

True

[('path', '/home/python'), ('version', '3.6.8\nBeta1'), ('author', 'Qing_Feng_Python'), ('number', '13'), ('creator', 'pymysql'), ('host', '127.0.0.1'), ('port', '3306'), ('user', 'root'), ('password', '123'), ('database', 'mysqlDB'), ('status', 'off'), ('uri', '[email protected]:3306/mysqlDB')]

127.0.0.1

False

[email protected]:3306/mysqlDB

Pycharm

大家可以看到,獲取option和items的時候,預設將DEFAULT中的引數也繼承進去了。
最後一行的變數解析,也正常顯示...
最後的寫入一定要切記,很多時候只是在記憶體中進行了新增刪除,而未進行檔案寫入,最終白玩一場....

關於列表的坑

在配置檔案的儲存時我用到了列表,類似如下方式:

index_list = [.......]

if x not  in index_list:
    index_list.append(x)
else:
    pass

一段很平常的程式碼,然後呢?問題讓我定位了好久,直接看個例子吧:

>>> index_list = [1,2,3]
>>> 2.0 not in index_list
False

其實這種情況在python中是普遍存在的,比如字典中

default_dict ={1:1,2:2}
default_dict[1.0]=2
default_dict
{1: 2, 2: 2}

為什麼?python字典的key儲存時,比較雜湊值來確定兩個鍵是否相同的

hash(1)==hash(1.0)
True

對於這些坑,你必須牢記在心,不然坑你沒商量....

好了,今天的內容就到這裡,如果覺得有幫助,記得點贊支援。

更多精彩內容,請滑至頂部點選右上角關注小宅哦~

https://zhuanlan.zhihu.com/p/69430734