python配置文件的读写
2020-09-01 本文已影响0人
_百草_
1. 配置文件configuration file
python中的配置文件有.conf
、.ini
、.cfg
、.txt
等多种,其中.ini
最常见
-
.ini
文件是Initialization File
的缩写,即初始化文件,是windows的系统配置文件所采用的存储格式。 - 一般用户就用windows提供的各项图形化管理界面就可实现相同的配置
- 但在一些情况,还是要直接编辑ini方便,一步只有很熟悉windows才能去直接编辑
1.1 配置文件的作用
- 变量参数化,不需要每次修改代码内部
- 模块化,可配置,提高代码重用性
1.2 配置文件的适用场景
- 多处使用同一个参数时,最好放置配置文件中(改动时修改一处即可,避免遗漏)
- 经常变化的变量(多次改动,直接修改配置文件,便利)
1.3 配置文件样式
[section] # 配置块
option = value
# 配置项 = 数据值
- section(配置块)使用
[]
方括号括起来 - section下,以
key = value
格式的键值对 -
value
默认类型为字符串,不需要首尾添加引号 - 使用
#
添加注释

注:
- 配置文件中,section唯一
- 同一section下,option唯一
2. python中配置文件的读取
python中读写配置文件,使用的是configparser.ConfigParser
2.1 模块导入和使用
from configparser import ConfigParser # 模块中类导入
conf = ConfigParser() # 创建配置文件对象
或者
import configparser # 模块导入
conf = configparser.ConfigParser() # 创建配置文件对象
2.2 read()读取配置文件
read(filenames, encoding=None)
# filenames可以是文件,也可以是目录,若是目录则依次读取各个配置文件
# filenames可以存在,也不可不存在;若不存在则新建配置文件
# 当前路径下,不需要添加dirname;若是非当前路径下,需要指定路径
# Return list of successfully read files.
实例:
res = conf.read("conf.ini", encoding="utf-8") # 读取配置文件 conf.ini
print(res) # ['conf.ini']
ERROR1:

配置文件中section重复,读取时,报错
configparser.DuplicateSectionError: While reading from 'conf.ini' [line 4]: section 'section2' already exists
ERROR2:

配置文件中,同一section下option重复,报错:
configparser.DuplicateOptionError: While reading from 'conf.ini' [line 6]: option 'op2' in section 'section1' already exists
2.3 get()获取配置文件内容
get(section, option) # 返回section下对应option的值
# section 配置块,不存在则报错:configparser.NoSectionError
# option 配置项,不存在则报错:configparser.NoOptionError
# 返回的字符串类型
# 需先读取read()或add_section配置文件,不然找不到对应的section
实例:

v1 = conf.get("section1", "op1") # 先读取配置文件再获取配置块中配置项的值
print(v1, type(v1)) # 100 <class 'str'>
v2 = conf.get("section1", "op2")
print(v2, type(v2)) # 13.14 <class 'str'>
v3 = conf.get("section1", "op3")
print(v3, type(v3)) # a100 <class 'str'>
v4 = conf.get("section1", "op4")
print(v4, type(v4)) # True <class 'str'>
2.3.1 getint()返回int类型
# 配置文件中配置项的值输入为整数,通过getint获取int型数值;其他的则报错ValueError
v1 = conf.getint("section1", "op1")
print(v1, type(v1)) # 100 <class 'int'>
v2 = conf.getint("section1", "op2") # ValueError: invalid literal for int() with base 10: '13.14'
print(v2, type(v2))
v3 = conf.getint("section1", "op3") # ValueError
print(v3, type(v3))
v4 = conf.getint("section1", "op4") # ValueError
print(v4, type(v4))
注:与int()区别
-
float
型的数值类型可以通过int()
转为int
型 - 配置文件中的
float
类型,不能通过getint()
转为int
型
# int()
v2 = 13.14
print(int(v2)) # 13
# getint()
v2 = conf.getint("section1", "op2") # ValueError: invalid literal for int() with base 10: '13.14'
print(v2, type(v2))
2.3.2 getfloat()返回float类型
# 配置文件中的int可以通过getfloat()获取float型
# 其他如string,getfloat()时,则报错
v1 = conf.getfloat("section1", "op1")
print(v1, type(v1)) # 100.0 <class 'float'>
v2 = conf.getfloat("section1", "op2")
print(v2, type(v2)) # 13.14 <class 'float'>
v3 = conf.getfloat("section1", "op3") # ValueError: could not convert string to float: 'a100'
print(v3, type(v3))
v4 = conf.getfloat("section1", "op4") # ValueError
print(v4, type(v4))
2.3.3 getboolean() 返回bool类型
# 配置文件中的true & false可以通过getboolean()获取
v1 = conf.getboolean("section1", "op1") # ValueError: Not a boolean: 100
print(v1, type(v1))
v2 = conf.getboolean("section1", "op2") # ValueError: Not a boolean: 13.14
print(v2, type(v2))
v3 = conf.getboolean("section1", "op3") # ValueError: Not a boolean: a100
print(v3, type(v3))
v4 = conf.getboolean("section1", "op4")
print(v4, type(v4)) # True <class 'bool'>
注:若配置文件中存放的是其他类型的数据,如dict、list、tuple,如何读取?
# eval(arg) 作用:直接去掉首尾的引号,将字符串转为其他类型;若不可识别则报错
h = conf.get("section2", "headers")
print(h, type(h)) # {"Content-Type": "image/jpeg;charset=UTF-8"} <class 'str'>
h = eval(h)
print(h, type(h)) # {'Content-Type': 'image/jpeg;charset=UTF-8'} <class 'dict'>
# eval实例
# 数值格式的字符串
s = eval("123")
print(s, type(s)) # 123 <class 'int'>
s = eval("baicao") # NameError: name 'baicao' is not defined
print(s, type(s))
# list格式的字符串
s1 = eval("[1, 2, 3]")
print(s1, type(s1)) # [1, 2, 3] <class 'list'>
# tuple格式的字符串
s2 = eval("(1, 2, 3)")
print(s2, type(s2)) # (1, 2, 3) <class 'tuple'>
# dict格式的字符串
s3 = eval("{'name':'百草'}")
print(s3, type(s3)) # {'name': '百草'} <class 'dict'>
2.4 section()、option()、items()获取配置块、配置项
# sections() 返回所有的section(从上到下依次),list类型
se = conf.sections()
print(se) # ['section1', 'section2']
# options(section) 返回section所有的option(从上到下的顺序),list类型
op = conf.options(section="section1")
print(op) # ['op1', 'op2', 'op3', 'op4']
# items(section) # 返回由 配置项和值的元组对 组成的list类型
ite = conf.items() #ItemsView(<configparser.ConfigParser object at 0x0061B3B0>)
print(ite)
print(list(ite)) # [('DEFAULT', <Section: DEFAULT>), ('section1', <Section: section1>), ('section2', <Section: section2>)]
ite = conf.items(section="section1")
print(ite) # [('op1', '100'), ('op2', '13.14'), ('op3', 'a100'), ('op4', 'true')]
3. python中配置文件的写入
3.1 add_section()添加section
# add_section(section_name)
# section_name:配置块的名称,字符串类型,其他类型则报错TypeError
# 添加后,需要写入配置文件,否则无效
conf.add_section("section3") # 添加section3
conf.add_section(123) # TypeError: section names must be strings
3.2 set() 设置配置项及对应的值
# set(section, option, value=None)
# value需要string类型,否则报错:TypeError: option values must be strings
conf.set("section4", "op2", "a100") # 添加值
# 设置时,配置项已存在,否则会报错:configparser.NoSectionError
注:
- 需要先读取(
read()
或add_section()
)配置文件,否则找不到对应的文件# configparser.NoSectionError: No section: 'section4'
- 设置后,需要写入配置文件,否则设置无效
3.3 write() 写入并保存配置文件
# write(self, fp, space_around_delimiters=True):
# Write an .ini-format representation of the configuration state.
# If `space_around_delimiters' is True (the default), delimiters between keys and values are surrounded by spaces.
conf.write(open("conf.ini", "w"))
# with open("conf.ini", "a") as f:
# conf.write(f)
# 该write()方法在写入后自动保存,可以不使用with方法
注:open(filename, mode)
-
a
模式,append即追加,会将所有读取过来的配置文件添加 -
w
模式,write即覆盖重写,会将新内容覆盖原来的内容
w 与 a 模式 实例:
from configparser import ConfigParser
conf = ConfigParser()
conf.read("conf.ini", "utf-8")
conf.set("section3", "op2", "a201")
conf.write(open("conf.ini", "w"))
w模式 | a模式 |
---|---|
![]() |
![]() |
另外,
ConfigParser 模块需要注意的是
不能区分大小写。
重新写入的配置文件不能保留原有配置文件的注释。
重新写入的配置文件不能保持原有的顺序。
不支持嵌套。
不支持格式校验 (即出现section重复等错误时,也可以正常写入;读取时方报错)