前言
使用配置檔案來靈活的配置一些參數是一件很常見的事情,配置檔案的解析并不複雜,在python裡更是如此,在官方釋出的庫中就包含有做這件事情的庫,那就是configParser
configParser解析的配置檔案的格式比較象ini的配置檔案格式,就是檔案中由多個section構成,每個section下又有多個配置項
ConfigParser簡介
ConfigParser 是用來讀取配置檔案的包。配置檔案的格式如下:中括号“[ ]”内包含的為section。section 下面為類似于key-value 的配置内容。
ConfigParser
子產品在python3中修改為
configparser
.這個子產品定義了一個ConfigParser類,該類的作用是使用配置檔案生效,配置檔案的格式和windows的INI檔案的格式相同
該子產品的作用 就是使用子產品中的
RawConfigParser()
、
ConfigParser()
SafeConfigParser()
這三個方法(三者擇其一),建立一個對象使用對象的方法對指定的配置檔案做增删改查 操作。
ini檔案結構
ini檔案結構需要注意一下幾點:
- 鍵值對可用
或者=
進行分隔:
-
的名字是區分大小寫的,而section
的名字是不區分大小寫的key
- 鍵值對中頭部和尾部的空白符會被去掉
- 值可以為多行
- 配置檔案可以包含注釋,注釋以
#
為字首;
注意:configparser有default_section的概念,預設為
[DEFAULT]
節,也就是之後的所有的section都有該預設section中的鍵值對,詳情參見configparser源碼的
__init__()
方法
一、使用ConfigParser類解析ini配置檔案
(PyCharm中實作)
實作查詢、添加、删除、儲存。
練習目的:
- 掌握檔案基本操作
- 認識ini檔案
- 了解ConfigParser類
使用ConfigParser類解析配置檔案
ini配置檔案的格式:
節: [session]
參數(鍵=值) name=value
1、解析mysql配置檔案
-
直接讀取檔案内容****read(filename)
-
擷取get(section, option)
下具體某一配置項的值(傳回的是字元串)section
-
得到所有的section,并以清單的形式傳回sections()
-
得到該section的所有optionoptions(section)
-
鍵值對的形式 得到該section的所有optionitems(section)
-
getint(section,option)
cnf.getboolean(section,option)
擷取整型、布爾型和浮點型的getfloat(section,option)
的值option
my.ini檔案示例:
[client]
port = 3306
user = mysql
password = mysql
host = 127.0.0.1
[mysqld]
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
skip-external-locking
2、ConfigParser類的使用方法
(1)建立configParser對象
In [1]: import configparser
In [2]: cf = configparser.ConfigParser(allow_no_value=True)
(2)讀取配置檔案内容
In [4]: cf.read('my.ini')
Out[4]: ['my.ini']
(3)擷取配置檔案資訊
- sections: 傳回一個包含所有章節的清單
- options: 傳回一個包含章節下所有選項的清單
- has_section: 判斷章節是否存在
- has_options: 判斷某個選項是否存在
- items: 以元組的形式傳回所有的選項
- get、getboolean、getint、getfloat: 擷取選項的值
同時需要注意
getboolean()
方法能判斷True/False的值有: ‘yes’/‘no’, ‘on’/‘off’, ‘true’/‘false’ 和 ‘1’/‘0’
In [4]: cf.sections() # 傳回一個包含所有章節的清單
Out[4]: ['client','mysq1d']
In [5]: cf.has_section('client') # 判斷章節是否存在
0ut[5]: True
In [6]cf.options('client ') # 判斷某個選項是否存在
Out[6]: ['port", 'user', 'password', 'host' ]
In [7]: cf.has_option('client', 'user') # 判斷某個選項是否存在
0ut[7]: True
In [8]: cf.get('client',' port') # 擷取選項的值
0ut[8]: '3306'
In [9]: cf.getint('client','port') # 擷取選項的值
0ut[9]: 3306
(4)修改配置檔案
常用方法:
- remove_section: 删除一個章節
- add_section: 添加一個章節
- remove_option: 删除一個選項
- set: 添加一個選項
- write: 将ConfigParser兌現中的資料儲存到檔案中
方法測試:
In [11]: cf.remove_section('client') # 删除一個章節
Out[11]: True
In [14]: cf.write(open('my.ini','w')) # 将ConfigParser兌現中的資料儲存到檔案中
#可在PyCharm中my.ini檔案檢視是否少了'client‘字段。
In [15]: cf.add.section('client') # 添加一個章節
In [16]: cf.set('client','port','3306') # 添加一個選項
In [17]: cf.set('client','user','mysq1') # 添加一個選項
In [18]: cf.set('client','password' 'mysq1') # 添加一個選項
In [19]: cf.set('client','host','127.0.0.1') # 添加一個選項
In [20]: cf.write(open('my.ini','w')) # 将ConfigParser兌現中的資料儲存到檔案中
#可在PyCharm中my.ini檔案檢視是否增加了'client‘字段。
In [21]: cf.remove_option('client', 'host') # 删除一個選項**
Out[21]: True
In [22]: cf.write(open('my.ini','w' )) # 将ConfigParser兌現中的資料儲存到檔案中
#可在PyCharm中my.ini檔案檢視是否減少了指定選項。
可在PyCharm上檢視測試效果。
3、常見異常
異常 | 描述 |
---|---|
ConfigParser.Error | 所有異常的基類 |
ConfigParser.NoSectionError | 指定的section沒有找到 |
ConfigParser.DuplicateSectionError | 調用add_section() 時,section名稱已經被使用 |
ConfigParser.NoOptionError | 指定的參數沒有找到 |
ConfigParser.InterpolationError | 當執行字元串插值時出現問題時,出現異常的基類 |
ConfigParser.InterpolationDepthError | 當字元串插值無法完成時,因為疊代次數超過了最大的範圍,是以無法完成。InterpolationError的子類 |
InterpolationMissingOptionError | 當引用的選項不存在時,會出現異常。InterpolationError的子類 |
ConfigParser.InterpolationSyntaxError | 當産生替換的源文本不符合所需的文法時,就會出現異常。InterpolationError的子類。 |
ConfigParser.MissingSectionHeaderError | 當試圖解析一個沒有分段标題的檔案時,會出現異常。 |
ConfigParser.ParsingError | 當試圖解析檔案時發生錯誤時,會出現異常 |
ConfigParser.MAX_INTERPOLATION_DEPTH | 當raw參數為false時,get()的遞歸插值的最大深度。這隻适用于ConfigParser類 |
二、查找檔案
PyCharm建立測試檔案,格式如下:
G:\四期\python\ConfigParser\files>tree /f
卷 學習 的檔案夾 PATH 清單
卷序列号為 7C11-994A
G:.
│ a.jpg
│ A.png
│ b.jpg
│ c.png
│ e.bmp
│ f.txt
│ ff.txt
│ find_file.py
│ find_file2.py
│ find_file3.py
│
└─test
測試一下
find_file.py
import os
for item in os.listdir('.'):
if os.path.isfile(item):
print(item)
輸出結果如下:
a.jpg
A.png
b.jpg
c.png
e.bmp
f.txt
ff.txt
find_file.py
find_file2.py
find_file3.py
1、使用fnmatch找到特定檔案
<1>fnmatch支援的通配符
字元 | 函數 |
---|---|
* | 比對所有字元 |
? | 比對單個字元 |
[seq] | 比對指定範圍内的字元 |
[!seq] | 比對不在指定範圍内的字元 |
<2>fnmatch的基本使用
fnmatch這個庫相對比較簡單,隻有4個函數,分别是fnmatch、fnmatchcase、filter和translate,其中最常用的是fnmatch。主要功能如下:
- fnmatch:判斷檔案名是否符合特定的模式。
- fnmatchcase:判斷檔案名是否符合特定的模式,區分大小寫。
- filter:傳回輸入清單中,符合特定模式的檔案名清單。
- translate:将通配符模式轉換成正規表達式。
fnmatch和fnmatchcase用法相同,判斷名稱是否符合表達式,傳回True or False
(1)fnmatch.fnmatch():一次隻能處理一個檔案
find_file2.py
import os
import fnmatch
for item in os.listdir('.'):
if os.path.isfile(item):
# if fnmatch.fnmatch(item,'*.jpg'):
# if fnmatch.fnmatch(item, '[a-e].*'):
# if fnmatch.fnmatch(item, '[a-z]?.txt'):
# if fnmatch.fnmatch(item, '[!a-c]*'):
print(item)
#輸出以“.jpg”為結尾的檔案
a.jpg
b.jpg
#輸出以“a-e”為标題的檔案
a.jpg
A.png
b.jpg
c.png
e.bmp
#輸出以“a-z”和一個任意字元為标題,并且以“.txt”為字尾的檔案
ff.txt
#輸出除了以“a-c”為開通的檔案
e.bmp
f.txt
ff.txt
find_file.py
find_file2.py
find_file3.py
(2)fnmath.filter():一次可以處理多個檔案
find_file3.py
import os
import fnmatch
items = os.listdir('.')
files = fnmatch.filter(items, '[a-c]*')
print(files)
['a.jpg', 'A.png', 'b.jpg', 'c.png']
2、使用glob找到特定檔案
glob子產品支援的通配符:
通配符 | 功能 |
---|---|
比對0或多個字元 | |
** | 比對所有檔案、目錄、子目錄和子目錄裡的檔案(3.5版本新增) |
? | 比對1個字元,與正規表達式裡的?不同 |
[exp] | 比對指定範圍内的字元,如:[1-9]比對1至9範圍内的字元 |
[!exp] |
标準庫glob的作用相當于os.listdir()加上fnmatch。使用glob以後,不需要調用os.listdir擷取檔案清單,直接通過模式比對即可。如下所示:
import glob
file = glob.glob('*.txt')
print(file)
['f.txt', 'ff.txt']
glob基本使用
>>> import glob
>>> glob.glob('*.txt')
['a1.txt', 'a2.txt', 'aA.txt']
>>> g = glob.iglob('*.txt') # 使用iglob傳回的是一個生成器
>>> g
<generator object _iglob at 0x1050bbba0>
>>> list(g)
['a1.txt', 'a2.txt', 'aA.txt']
>>>
>>> glob.glob('/Users/DahlHin/github/test/*.txt')
['/Users/DahlHin/github/test/a1.txt','/Users/DahlHin/github/test/a2.txt','/Users/DahlHin/github/test/aA.txt']