python config配置檔案的讀寫

Mr-Cat伍可貓發表於2020-10-10


參考文獻:
【1】 python讀取配置檔案&&簡單封裝
【2】 python 中使用ConfigParser類修改配置檔案
【3】 python3中的RE(正規表示式)-總結

1 基礎知識

python裡面需要使用到configparser包,可以使用pip安裝

pip install configparser

在配置檔案裡面,預設使用[ ]表示section,如下config.ini檔案表示有兩個節:

[user1]
user_ip = 127.0.0.1
user_name = testuser1
user_id = 45

[user2]
user_ip = 127.0.0.2
user_name = testuser2
user_id = 41

2 讀取配置檔案

下面程式碼有註釋,關於使用os寫相對路徑,可以看參考文獻【1】

import configparser

cf = configparser.ConfigParser()
cf.read("config.ini")  # 讀取配置檔案,如果寫檔案的絕對路徑,就可以不用os模組

secs = cf.sections()  # 獲取檔案中所有的section(一個配置檔案中可以有多個配置,如資料庫相關的配置,郵箱相關的配置,
                      #  每個section由[]包裹,即[section]),並以列表的形式返回
print(secs)

options = cf.options("user1")  # 獲取某個section名為user1所對應的鍵
print(options)

items = cf.items("user1")  # 獲取section名為user1所對應的全部鍵值對
print(items)

name = cf.get("user1", "user_name")  # 獲取user1中user_name對應的值
print(name)

在這裡插入圖片描述

3 改寫配置檔案

已知原始config.ini檔案如下

[user1]
user_ip = 127.0.0.1
user_name = testuser1
user_id = 45

[user2]
user_ip = 127.0.0.2
user_name = testuser2
user_id = 41

寫一個write_config.py來更改配置檔案

import configparser
import numpy as np
import copy

conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)
node = "user1"   #改user1
key = "user_id"
value = "00"
conf.set(node, key, value)
fh = open(filename, 'w')
conf.write(fh)  # 把要修改的節點的內容寫到檔案中
fh.close()

執行此檔案之後,發現配置檔案變了

[user1]
user_ip = 127.0.0.1
user_name = testuser1
user_id = 00   #改為00

[user2]
user_ip = 127.0.0.2
user_name = testuser2
user_id = 41

使用for迴圈將兩個user同時改

import configparser
import numpy as np
import copy

conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)

secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']

ip_key = 'user_ip'
name_key = 'user_name'
id_key = 'user_id'

for i in range(len(secs)):
    conf.set(secs[i], ip_key,user_ip[i])
    conf.set(secs[i], name_key, user_name[i])
    conf.set(secs[i], id_key, user_id[i])
    fh = open(filename, 'w')
    conf.write(fh) 
fh.close()

當然,conf.set可以直接指定欄位,不用重新命名

import configparser
import numpy as np

conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)

secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']

for i in range(len(secs)):
    conf.set(secs[i], 'user_ip', user_ip[i])
    conf.set(secs[i], 'user_name', user_name[i]) #直接指定欄位
    conf.set(secs[i], 'user_id', user_id[i])
    fh = open(filename, 'w')
    conf.write(fh) 
fh.close()

結果為

[user1]
user_ip = 192.168.0
user_name = python
user_id = 111

[user2]
user_ip = 192.168.1
user_name = python1
user_id = 222

以上都是沒有寫成類的,要寫成類的形式可以看參考文獻【1】

3.1 刪除section

config.remove_option('user1', 'user_ip')# 刪除user1分組的user_ip
config.remove_section('user1')# 刪除配置檔案中user1分組(會將整個user1下的ip,id,name都刪除)

更多關於config的使用可以看官網


現在有另一個需求:將修改後的配置檔案儲存到一個名為config.txt的檔案中,並去掉中括號內的字元,即去掉[user1],[user2]
上面的程式碼,實際上修改完之後通過open可以寫入到新檔案中(原檔案的內容不會改變)

for i in range(len(secs)):
    conf.set(secs[i], 'user_ip', user_ip[i])
    conf.set(secs[i], 'user_name', user_name[i]) #直接指定欄位
    conf.set(secs[i], 'user_id', user_id[i])
    #fh = open(filename, 'w')
    fh = open('config.txt','w')  #檔案另存到config.txt中
    conf.write(fh) 
fh.close()

現在需要將[user1],[user2]欄位去掉,一個方法是將它們替換為空。比如這裡將[user2]改為空,即``,注意不是表示的空格,而是none。

import configparser
import numpy as np

conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)

secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']

for i in range(len(secs)):
    conf.set(secs[i], 'user_ip', user_ip[i])
    conf.set(secs[i], 'user_name', user_name[i]) #直接指定欄位
    conf.set(secs[i], 'user_id', user_id[i])
    #fh = open(filename, 'w')
    fh = open('config.txt','w')  #檔案另存到config.txt中
    conf.write(fh) 
fh.close()

#將[user2]去掉
with open('config.txt', 'r') as fpr:
    content = fpr.read()
content = content.replace('[user2]', '')
with open('config.txt', 'w') as fpw: #如果要另存為a.txt,則將config.txt改為a.txt
    fpw.write(content)

結果如下
在這裡插入圖片描述
另外,可以使用正規表示式

import re

# read file
f1 = open('config.txt','r')
f2 = open('a.txt','w')

# write file
for ss in f1.readlines():
    a = re.sub(r'\[user2\]','',ss)
    f2.write(a)

f1.close()
f2.close()

在這裡插入圖片描述

上面需要注意,正規表示式如果沒有斜槓,\[user\],會表示將所有的user都換掉,包括user_id等裡面的user字元都去掉。那麼既然使用了正規表示式,就可以將user1,user2同時去掉了,可以規定但凡有[user*的都去掉(*表示後面所有)或者但凡user後有數字接著的都去掉。這部分可以看參考文獻【3】
所以只需要將上面的程式碼改為:

# read file
f1 = open('config.txt','r')
f2 = open('a.txt','w')

# write file
for ss in f1.readlines():
    a = re.sub(r'\[user\d\]','',ss)  #\d表示匹配0-9數字
    f2.write(a)

f1.close()
f2.close()

結果為
在這裡插入圖片描述
至此,完整程式碼如下:

import configparser
import numpy as np
import re

conf = configparser.ConfigParser()
filename = "config.ini"
conf.read(filename)

secs = conf.sections()
user_ip = ['192.168.0','192.168.1']
user_name = ['python','python1']
user_id = ['111','222']

for i in range(len(secs)):
    conf.set(secs[i], 'user_ip', user_ip[i])
    conf.set(secs[i], 'user_name', user_name[i]) #直接指定欄位
    conf.set(secs[i], 'user_id', user_id[i])
    #fh = open(filename, 'w')
    fh = open('config.txt','w')  #檔案另存到config.txt中
    conf.write(fh) 
fh.close()

# read file
f1 = open('config.txt','r')
f2 = open('a.txt','w')

# write file
for ss in f1.readlines():
    a = re.sub(r'\[user\d\]','',ss)
    f2.write(a)

f1.close()
f2.close()

相關文章