Python实现解析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 的库,这个库是自带的,我们可以直接用。

import configparser

# 实例化一个 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) for k, v in config.items()})
\"\"\"
{\'DEFAULT\': {}, 
 \'satori\': {\'name\': \'古明地觉\', 
            \'age\': \'16\', 
            \'where\': \'东方地灵殿\'}, 
 \'koishi\': {\'name\': \'古明地恋\', 
            \'age\': \'15\', 
            \'where\': \'东方地灵殿\'}, 
 \'marisa\': {\'name\': \'雾雨魔理沙\', 
            \'age\': \'17\', 
            \'where\': \'魔法森林\'}}
\"\"\"

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

import configparser

# 实例化一个 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\"

with open(\"cfg.ini\", \"w\", encoding=\"utf-8\") as f:
    config.write(f)

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

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

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

特殊格式

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

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

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

import configparser

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

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

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

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

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

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

import configparser

# \"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 之间还可以发生引用。

import configparser

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 要怎么做呢?

import configparser

# 指定该参数之后,我们就不能通过 %(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配置文件的资料请关注其它相关文章!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容