Python实现解析ini配置文件的示例详解

2022-09-16 09:41:20

目录楔子ini文件特殊格式小结楔子在开发过程中,配置文件是少不了的,只不过我们有时会将py文件作为配置文件(config.py),然后在其它的模块中直接导入。这样做是一个好主意,不过配置文件是有...

目录
楔子
ini 文件
特殊格式
小结

楔子

在开发过程中,配置文件是少不了的,只不过我们有时会将 py 文件作为配置文件(config.py),然后在其它的模块中直接导入。这样做是一个好主意,不过配置文件是有专门的格式的,比如:ini, yaml, toml 等等。

而对于 python 而言,也都有相应的库来解析相应格式的文件,下面我们来看看 ini 文件要如何解析。

ini 文件

先来了解一下 ini 文件的格式:

[satori]
name=古明地觉
age=16
where=东方地灵殿

[koishi]
name=古明地恋
age=15
where=东方地灵殿

[marisa]
name=雾雨魔理沙
age=17
where=魔法森林

; 以分号或井号开头表示注释,不影响

ini 文件总分可以分为三块,分别是:

section:就是写在 [] 里面的内容,可以把它理解为一个段;
parameter:以 key = value  的形式出现,比如 age = 16,那么 age 就是 key、16 就是 value,注意:每个 section 都有自己的 parameter;
注释:以分号开头,无影响,会被忽略掉。

可以看到结构还是比较清晰的,那么 Python 要如何解析呢?Python 解析 ini 文件需要使用一个名叫 configparser 的库,这个库是自带的,我们可以直接用。

importconfigparser

#实例化一个ConfigParser实例
config=configparser.ConfigParser()
#打开ini文件
config.read("cfg.ini",encoding="utf-8")

#获取所有的section
print(config.sections())
"""
['satori','koishi','marisa']
"""

#获取某一个section的所有parameter
print(config["satori"])
"""
<Section:satori>
"""

#我们可以像操作字典一样操作parameter
print(list(config["satori"]))
"""
['name','age','where']
"""
print(list(config["satori"].values()))
"""
['古明地觉','16','东方地灵殿']
"""
print(list(config["satori"].items()))
"""
[('name','古明地觉'),('age','16'),('where','东方地灵殿')]
"""
#获取某个key对应的value
#如果key不存在则抛出KeyError
print(config["marisa"]["where"])
"""
魔法森林
"""
#也可以调用get方法
#在key不存在时,指定一个默认值
print(config["marisa"].get("age"))
"""
17
"""
#我们发现age居然是一个字符串
#因为默认解析得到的都是字符串
print(config["marisa"]["age"].__class__)
"""
<class'str'>
"""

#可以通过getint获取
#会将value转成整型,但转化失败的话会报错
#除了getint之外,还有getfloat、getboolean
print(config["marisa"].getint("age")==17)
"""
True
"""

#最后也可以直接转成字典
print(dict(config["koishi"]))
"""
{'name':'古明地恋','age':'15','where':'东方地灵殿'}
"""
print(dict(config))
"""
{'DEFAULT':<Section:DEFAULT>,
'satori':<Section:satori>,
'koishi':<Section:koishi>,
'marisa':<Section:marisa>}
"""
print({k:dict(v)fork,vinconfig.items()})
"""
{'DEFAULT':{},
'satori':{'name':'古明地觉',
'age':'16',
'where':'东方地灵殿'},
'koishi':{'name':'古明地恋',
'age':'15',
'where':'东方地灵殿'},
'marisa':{'name':'雾雨魔理沙',
'age':'17',
'where':'魔法森林'}}
"""

可以看到还是比较容易的,因为 ini 这种文件格式本身就很简单。除了读取文件,我们还可以进行写入。

importconfigparser

#实例化一个ConfigParser类的实例
config=configparser.ConfigParser()
config["basic"]={"Host":"127.0.0.1",
"Port":"8888",
"Username":"satori"}

config["thread"]={}
config["thread"]["name"]="my_thread"
config["thread"]["num"]="3"

withopen("cfg.ini","w",encoding="utf-8")asf:
config.write(f)

Python实现解析ini配置文件的示例详解

虽然成功写入了,但是我们看到结果变成了小写。是的,对于 parameter 来说,无论是大写还是小写,写入文件的时候都会变成小写。然后读取也是,无论 ini 文件中是大写还是小写,读取之后都会变成小写。

注意:大小写不敏感只是针对于 parameter,对于 section 来说还是区分大小写的。

特殊格式

我们上面配置的 parameter 中的 key, value 都是一个普通的单词,但其实我们还可以配置的更加复杂一些。

Python实现解析ini配置文件的示例详解

我们操作一波,看看能否正常解析。

importconfigparser

#实例化一个ConfigParser实例
config=configparser.ConfigParser()
#打开ini文件
config.read("cfg.ini",encoding="utf-8")

print(dict(config["简单值"]))
"""
{'键':'值',
'键里面有空格':'合法',
'值里面有空格':'也合法',
'等号周围有空格':'仍然合法',
'你也使用':'代替等号'}
"""

print(dict(config["所有值都是字符串"]))
"""
{'这是字符串':'123',
'这也是字符串':'3.14',
'整数、浮点数、布尔值都是字符串':'true'}
"""
#trueTrueyes都可以转成布尔值True
#falseFalseno都可以转成布尔值Fapythonlse
print(config["所有值都是字符串"].getboolean(
'整数、浮点数、布尔值都是字符串'))
"""
True
"""

print(dict(config["值占多行"]))
"""
{'洪世贤':'你怎么穿品如的衣服啊\n还用人东西'}
"""

print(dict(config["值为空字符串"]))
"""
{'key1':'','key2':''}
"""

结果是正常的,但是很明显上面这种做法有点闲的没事了,以后就统一写成 key = value 的形式即可。另外如果 ini 文件中只有 key 没有 value 的话,默认是报错的,但可以通过一个参数改变这一点:

importconfigparser

#"key="这种形式不叫没有值,它是有值的,值为空字符串
#"key"这种形式才是没有值,解析的时候默认会报错
#可以通过一个参数改变这一点
config=configparser.ConfigParser(allow_no_value=True)
config.read_string(
"""
[mysqld]
user=mysql
skip-bdb
""")
print(dict(config["mysqld"]))
"""
{'user':'mysql','skip-bdb':None}
"""

除此之外,name 之间还可以发生引用。

importconfigparser

config=configparser.ConfigParser()

#可以通过%(key)s的方式对同一个section中的其它key进行引用
#所编程客栈以如果想表示一个%的话,需要写两个%,因为涉及到转义
config.read_string("""
[section1]
user=古明地觉
age=16
info=%(user)s--%(age)s
percent=80%%
""")

print(dict(config["section1"]))
"""
{'user':'古明地觉','age':'16',
'info':'古明地觉--16','percent':'80%'}
"""

还是很简单的,如果想引用其它的 section 中的 name 要怎么做呢?

importconfigparser

#指定该参数之后,我们就不能通过%(name)s的方式引用了
#需要使用${name}这种格式,显然更方便了
config=configparser.ConfigParser(
interpolation=configparser.ExtendedInterpolation()
)

config.read_string("""
[DEFAULT]
默认的=自动加入到每一个section中

[section1]
user=古明地觉
age=16
info=${user}--${age}

[section2]
info=${section1:user},${section1:age}
""")

print(dict(config["section1"]))
"""
{'user':'古明地觉',
'age':'16',
'info':'古明地觉--16',
'默认的':'自动加入到每一个section中'}
"""
print(dict(config["section2"]))
"""
{'info':'古明地觉,16',
'默认的':'自动加入到每一个section中'}
"""

小结

以上就是 ini 文件的一些简单用法,以后我们在写配置的时候,不妨使用一些专门用来表示配置的文件格式,不一定非要写在 py 文件里面。

而且使用 ini 等配置文件的一个好处就是,即便不懂 Python 的人也能看懂;或者这个配置文件不一定是要由你来写,可能是别人写,而那个人不用 Python,但是通过 ini 文件的话就省去了沟通的成本。

后续我们继续介绍其它种类的配置文件,比如 yaml, toml,因为 ini 虽然简单,但表达能力还是很有限的。而 yaml 和 toml 的表达能力要更丰富,应用领域也要更广一些。

以上就是Python实现解析ini配置文件的示例详解的详细内容,更多关于Python解析ini配置文件的资料请关注我们其它相关文章!