python的ConfigParser函數和查找文件的方法(listdir,fnmatc,glod)

前言

  使用配置文件來靈活的配置一些參數是一件很常見的事情,配置文件的解析並不複雜,在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 下具體某一配置項的值(返回的是字符串)
  • sections() 得到所有的section,並以列表的形式返回
  • options(section) 得到該section的所有option
  • items(section) 鍵值對的形式 得到該section的所有option
  • 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基本使用

glob和iglob的區別在於glob返回的是一個列表,iglob返回的是一個生成器對象

>>> 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']
>>>

PS:glob同樣支持通配符和fnmatch相同,這裏不在列舉,並且在通配符表達式中支持路徑

>>> 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']

總結:雖然glob模塊可以很輕鬆地匹配特定文件和文件夾,但是僅僅支持少量的通配符,沒辦法像正則表達式一樣匹配更復雜的字符串。使用的時候應當認真考慮使用場景,根據需求針對性地選擇解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章