Z.S.K.'s Records

Python学习(全局配置文件引用问题)

在python工程代码中, 配置文件的引用是一定无法躲避的问题, 最次的办法是每次调用一个读取配置文件的函数,获得需要的变量

但是如果配置文件的格式是ini、yaml、json等富文本的形式呢?每次还得进行解析, 显然不是很好, 有更pythonic的方法么?

python里有configparse库可以方便我们进行配置文件的解析, 同时也支持多种格式

经过一番研究之后还得觉得跟我想要的效果差点什么?

然后我去看了django的配置文件是如何实现全局效果的,恍然大悟. That’s it.

这里以yaml格式的配置文件为例,目录结构

假如所有的配置文件都放在conf/global.yml文件中

1
2
3
4
5
6
7
topdir
- conf
- __init__.py
- global.yml # yaml格式的配置文件
- bin
- app
- app.py

global.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
default:
# 基础配置
uniall:
url: 'https://baidu.com'
http:
# 功能重试次数
func_retries: 1
# 功能重试时 延迟时间, 单位: 秒
func_retry_delay_seconds: 10
# http 重试次数
http_max_retries: 2
# http 超时时间, 单位: 秒
http_timeout: 10
...

dev:
http:
...
...

conf/__init__.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/env python
# -*- coding: utf-8 -*-


import os
from yaml import load

try:
from yaml import CLoader as Loader
except ImportError:
from yaml import Loader


class Get_Config(object):
def __init__(self, path="global.yml", mode="default"):
self.path = path
self.mode = mode
self.cfg = None

def parse_conf(self):
if os.path.exists(self.path):
with open(self.path, "rt") as fh:
config = load(fh, Loader=Loader)
cfg = config[self.mode]
else:
raise ValueError("CONFIG FILE NOT FOUND")
os._exit(1)
return cfg


CONF_PATH = os.path.dirname(os.path.abspath(__file__))
cfg = Get_Config(path="{}/global.yml".format(CONF_PATH), mode="default").parse_conf()

在多个环境下同一份配置文件时, mode则变得非常有用, 只会解析mode对应的配置

这里用到了__init__.py这个文件的magic, 在导入时会自动地执行.

这样, 在app/app.py等其它文件中如果需要使用配置文件,则只需要导入cfg即可

然后像使用字典一样引用配置就行

1
2
3
from conf import cfg

cfg["http"]["func_retry_delay_seconds"]

参考文章:

转载请注明原作者: 周淑科(https://izsk.me)

 wechat
Scan Me To Read on Phone
I know you won't do this,but what if you did?