600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > python config配置文件的读写--configparser

python config配置文件的读写--configparser

时间:2021-12-17 05:47:39

相关推荐

python config配置文件的读写--configparser

文章目录

1 基础知识2 读取配置文件3 改写配置文件3.1 删除section3.2 字符串大小写问题4 实例4.1 1维两层的数据4.2 多维两层的数据4.3 使用am运行得到的文件

参考文献:

【1】python读取配置文件&&简单封装

【2】python 中使用ConfigParser类修改配置文件

【3】python3中的RE(正则表达式)-总结

1 基础知识

python里面需要使用到configparser包,可以使用pip安装

pip install configparser

在配置文件里面,默认使用[ ]表示section,如下config.ini文件表示有两个节:

[user1]user_ip = 127.0.0.1user_name = testuser1user_id = 45[user2]user_ip = 127.0.0.2user_name = testuser2user_id = 41

2 读取配置文件

下面代码有注释,关于使用os写相对路径,可以看参考文献【1】

import configparsercf = 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.1user_name = testuser1user_id = 45[user2]user_ip = 127.0.0.2user_name = testuser2user_id = 41

写一个write_config.py来更改配置文件

import configparserimport numpy as npimport copyconf = configparser.ConfigParser()filename = "config.ini"conf.read(filename)node = "user1" #改user1key = "user_id"value = "00"conf.set(node, key, value)fh = open(filename, 'w')conf.write(fh) # 把要修改的节点的内容写到文件中fh.close()

更新:

上面的写入文件代码

fh = open(filename, 'w')conf.write(fh) # 把要修改的节点的内容写到文件中

可能在某些文件中最后一行会有问题,所以将之改为(下面所有代码都这么改即可)

with open('config.txt', 'w') as configfile:conf.write(configfile)

运行此文件之后,发现配置文件变了

[user1]user_ip = 127.0.0.1user_name = testuser1user_id = 00 #改为00[user2]user_ip = 127.0.0.2user_name = testuser2user_id = 41

使用for循环将两个user同时改

import configparserimport numpy as npimport copyconf = 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 configparserimport numpy as npconf = 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.0user_name = pythonuser_id = 111[user2]user_ip = 192.168.1user_name = python1user_id = 222

以上都是没有写成类的,要写成类的形式可以看参考文献【1】

3.1 删除section

config.remove_option('user1', 'user_ip')# 删除user1分组的user_ipconfig.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 configparserimport numpy as npconf = 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.txtfpw.write(content)

结果如下

另外,可以使用正则表达式

import re# read filef1 = open('config.txt','r')f2 = open('a.txt','w')# write filefor 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 filef1 = open('config.txt','r')f2 = open('a.txt','w')# write filefor ss in f1.readlines():a = re.sub(r'\[user\d\]','',ss) #\d表示匹配0-9数字f2.write(a)f1.close()f2.close()

结果为

至此,完整代码如下:

import configparserimport numpy as npimport reconf = 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])with open('config.txt', 'w') as configfile:conf.write(configfile)configfile.close()# read filef1 = open('config.txt','r')f2 = open('a.txt','w')# write filefor ss in f1.readlines():a = re.sub(r'\[user\d\]','',ss)f2.write(a)f1.close()f2.close()

3.2 字符串大小写问题

源包configparser中设置的输出都是小写的,比如把上面例题中的user_ip改为User_ip,即首字母大写,结果运行完之后得到的却依然是user_ip这是因为在configparser包中定义的输出为小写

def optionxform(self, optionstr):return optionstr.lower()#转小写字母

因此我们可以自己写一个函数,替换掉optionxform,即

import configparserclass Myconf(configparser.ConfigParser):def __init__(self, defaults=None):configparser.ConfigParser.__init__(self, defaults=None) #继承父类def optionxform(self, optionstr):return optionstr #没有改为小写conf = Myconf()

4 实例

这是本人需要解决的一个问题,不感兴趣的读者可以不往下看了,仅作为笔者笔记使用

4.1 1维两层的数据

相当于望远镜只朝天上看一个方向,这个方向上把水汽分成两层,每层得到一组数据

即数据如下:

Pbase = ['542', '542']Tbase = ['268.6', '268.6']column_h2o_vmr = ['5.49e-04', '5.49e-04']column_o3_vmr = ['4.38e-08', '4.38e-08']

具体过程如下:

现在有一个名为onelayer.amc的文件

? Example:? am test.amc 0 GHz 300 GHz 10 MHz 0 deg?f %1 %2 %3 %4 %5 %6output f GHz Tb Kjacobian Tbza %7 %8tol 1e-4Nscale troposphere h2o 1.0T0 2.7 Klayer tropospherePbase 542 mbar Tbase 368.6 K column dry_air vmrcolumn h2o vmr 5.49e-04column o3 vmr 4.38e-08layer tropospherePbase 542 mbar Tbase 368.6 K column dry_air vmrcolumn h2o vmr 5.49e-04column o3 vmr 4.38e-08

现在需要对其修改layer troposphere下面的Pbase,Tbase等参数,使用configparser。(我相信肯定有更好的办法,欢迎留言)

首先要修改onelayer.amc文件到config.ini中,如下(注意配置文件一定是xx=yy的形式,没有=会报错的,所以临时修改了一些量,使得都含有=号,最后再想办法用正则表达式去掉=号即可)

[layer 2]layer=tropospherePbase=542 mbarTbase=268.6 K column_dry_air=vmrcolumn_h2o_vmr=5.49e-04column_o3_vmr=4.38e-08[layer 1]layer=tropospherePbase=542 mbarTbase=268.6 K column_dry_air=vmrcolumn_h2o_vmr=5.49e-04column_o3_vmr=4.38e-08

然后在需要最后写入的文件a.txt中将前面部分不需要改动的写进去,之后在写入每个layer troposphere的时候通过追加的形式。

? Example:? am test.amc 0 GHz 300 GHz 10 MHz 0 deg?f %1 %2 %3 %4 %5 %6output f GHz Tb Kjacobian Tbza %7 %8tol 1e-4Nscale troposphere h2o 1.0T0 2.7 K

所以所有的文件大概关系是

运行write_config.py得到a.txt文件为:

源码如下

import configparserimport numpy as npimport reclass Myconf(configparser.ConfigParser):def __init__(self, defaults=None):configparser.ConfigParser.__init__(self, defaults=None)def optionxform(self, optionstr):return optionstrconf = Myconf()filename = "config.ini"conf.read(filename)secs = conf.sections()Pbase = ['542', '542']Tbase = ['268.6', '268.6']column_h2o_vmr = ['5.49e-04', '5.49e-04']column_o3_vmr = ['4.38e-08', '4.38e-08']for i in range(len(secs)):conf.set(secs[i], 'Pbase', Pbase[i]+' mbar') #加入单位mbarconf.set(secs[i], 'Tbase', Tbase[i]+' K') #直接指定字段conf.set(secs[i], 'column_h2o_vmr', column_h2o_vmr[i])conf.set(secs[i], 'column_o3_vmr', column_o3_vmr[i])#文件另存到config.txt中with open('config.txt', 'w') as configfile:conf.write(configfile)configfile.close()# read filef1 = open('config.txt','r')f2 = open('a.txt','a') #追加的形式# write filefor ss in f1.readlines():ss = re.sub(r'\[layer \d\]','',ss)ss = re.sub('layer = troposphere', 'layer troposphere',ss)ss = re.sub(r'base =',r'base',ss)ss = re.sub('column_dry_air = vmr', 'column dry_air vmr',ss)ss = re.sub('column_h2o_vmr =', 'column h2o vmr', ss)ss = re.sub('column_o3_vmr =', 'column o3 vmr', ss)f2.write(ss)f1.close()f2.close()

4.2 多维两层的数据

相当于望远镜只朝天上看一个方向,这个方向上把水汽分成两层,每层得到一组数据;然后移动望远镜一定的距离又得到另一个方向上的数据。

Pbase = [['542', '500'],['530','480']] #二维数据,每个维度表示一个方向上的点Tbase = [['268.6','250'], ['265','258']]column_h2o_vmr = [['5.49e-04','5.41e-04'], ['5.43e-04','5.40e-04']]column_o3_vmr = [['4.4e-08','4.3e-08'],['4.50e-08', '4.38e-08']]

具体过程如下:

我们现在要把每个方向上观测到的点放入单个文件中,即一个文件表示一个方向。

首先我们要把前缀部分统一写入多个文件,以两个方向为例,即两个文件

先建立一个只有前缀的prefix.amc文件

将上面的文件写入每个文件中,即写入a0.amc, a1.amc中,相当于拷贝

#write prefix to files:for j in range(len(Pbase)):prefix_file = open('prefix.amc', 'r')f0 = open('a'+str(j)+'.amc','w')text = prefix_file.read()f0.write(text)f0.close()prefix_file.close()

然后就可以开始上面同样的过程了(这里我把for放一起了),完整代码如下:

import configparserimport numpy as npimport reclass Myconf(configparser.ConfigParser):def __init__(self, defaults=None):configparser.ConfigParser.__init__(self, defaults=None)def optionxform(self, optionstr):return optionstrconf = Myconf()filename = "config.ini"conf.read(filename)secs = conf.sections()Pbase = [['542', '500'], ['530', '480']] # 二维数据,每个维度表示一个方向上的点Tbase = [['268.6', '250'], ['265', '258']]column_h2o_vmr = [['5.49e-04', '5.41e-04'], ['5.43e-04', '5.40e-04']]column_o3_vmr = [['4.4e-08', '4.3e-08'], ['4.50e-08', '4.38e-08']]#write prefix to files:for j in range(len(Pbase)):prefix_file = open('prefix.amc', 'r')f0 = open('a'+str(j)+'.amc','w')text = prefix_file.read()f0.write(text)f0.close()prefix_file.close()for j in range(len(Pbase)):for i in range(len(secs)):conf.set(secs[i], 'Pbase', Pbase[j][i]+' mbar') #加入单位mbarconf.set(secs[i], 'Tbase', Tbase[j][i]+' K') #直接指定字段conf.set(secs[i], 'column_h2o_vmr', column_h2o_vmr[j][i])conf.set(secs[i], 'column_o3_vmr', column_o3_vmr[j][i])#文件另存到config.txt中with open('config'+str(j)+'.txt', 'w') as configfile:conf.write(configfile)configfile.close()f1 = open('config'+str(j)+'.txt', 'r')f2 = open('a'+str(j)+'.amc', 'a')# write filefor ss in f1.readlines():ss = re.sub(r'\[layer \d\]', '', ss)ss = re.sub('layer = troposphere', 'layer troposphere', ss)ss = re.sub(r'base =', r'base', ss)ss = re.sub('column_dry_air = vmr', 'column dry_air vmr', ss)ss = re.sub('column_h2o_vmr =', 'column h2o vmr', ss)ss = re.sub('column_o3_vmr =', 'column o3 vmr', ss)f2.write(ss)f2.close()f1.close()

得到两个文件,a1.amc如下

4.3 使用am运行得到的文件

这部分由于要使用am在终端运行,所以得要借助shell命令,

参考shell运行文件

建立一个名为run.sh的文件,内容为:

由于间隔是2GHz,所以只会输出100GHz对于的值

补充:上面的的>表示输出到文件,而如果使用>>则表示追加,即在原文件后累加。

如我将上面的>改为>>,则得到的结果如下:

现在有两个文件a0.amc, a1.amc所以需要使用for循环,参考另一博文

因为采用的是seq这种for循环,必须从1开始(尝试了其他的循环都没有效果)

所以对上面一开始的文件做如下处理:

1)将文件a0.amc改为a2.amc2)由于am运行的时候底下最低的一层Pbase似乎是要大于550 mbar,所以将值改为大于550的任意值即可

现在开始写run.sh文件

使用追加的形式,将运行结果统一放置在a.out中,运行结束会输出done

运行run.sh,有两种方法

1,直接sh运行

sh run.sh

2, 给定权限之后运行

chmod +x run.sh./run.sh

得到结果

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。