python配置环境变量方法(Python处理本地配置文件和配置值)

ini配置格式

我们项目一般本地配置文件用INI格式或者json格式,还有Yaml和XML用的也比较普遍。Yaml是2001年首次发表,现在大数据和AI很多配置调用Yaml,本文只介绍最通用的跨语言跨平台配置INI和JSON。

INI格式是大家比较熟悉的文件格式,由section和key=value构成,支持备注,用英文分号(;)开头备注。一般文件命名后缀用小写的ini。大部分时候,配置文件更多的用ini,作为配置文件,它有2个优势

  • 简单。两个层级,第一层级是section,第二层级是KV,JSON层级没有约束,因为可以嵌套,层级不确定
  • 支持备注。配置项大部分时候会开放给用户,或者其他开发者使用,适当的备注是很重要的。根据JSON的规范,是不支持备注的,当然也可以采用新增kv备注,或者配置中有注释,读取时去配置等规避方法,但总感觉别扭。

INI配置文件层级更明确,备注方便,使用无歧义,因此应用更加广泛,但INI配置不关注配置值类型,需要解析代码自己处理。

python配置环境变量方法(Python处理本地配置文件和配置值)(1)

如下是一个简单的例子

;用户配置 [user] ;姓名 name=Lily ;年龄 age=11

Python处理INI配置

python的configparser库处理INI非常简单,声明一个ConfigParser对象,调用read方法直接从文件中读取配置,则可以使用config引用配置项了。 要保存到文件,使用write方法写回文件即可,不过写回文件,备注会自动清除[捂脸]。写回不做详细介绍,因为一般是人工修改配置,程序读取配置。

from configparser import ConfigParser config_file = "/home/your_cfg.ini" config = ConfigParser() # 读取配置 config.read(config_file, encoding="utf-8") # 读取调试模式参数 debug_mode = config.get("RUN", "debug_mode", fallback="False") == "true"

如上第7行,通过config对象的get方法读取配置,第一个参数是section,第二个参数是key值,fallback参数表示如果该配置在ini中没有,那返回的值是什么。

前面已经描述,从INI中读取的值没有类型,都是字符串,需要代码自己处理,那debug_mode的处理就是读取section为RUN的小节中, key为debug_mode对应的配置值,如果为true则处理为Python的bool真True,否则为否False

下面简要描述配置值和对应代码获取到的结果

  • 配置为True

[RUN] debug_mode=true

  • 无配置默认False(备注掉了就是未配置了)

[RUN] ;debug_model=True

  • 配置为其他值也是False

[RUN] debug_mode=f

JSON配置格式

JSON全称叫JavaScript Object Notation(没错,看前面是github上最广泛的语言JS[赞]),它是一种轻量级的数据交换格式。一般HTTP中,前后端通过RestFUL风格接口来交互,那数据交换格式就会经常采用JSON方式,JSON不光协议轻量级,同时还能保持原有字段类型

python配置环境变量方法(Python处理本地配置文件和配置值)(2)

JSON格式比较简单,支持KV格式,花括号{}包起来,key和value用冒号:隔开,每组kv用逗号隔开;或者列表形式,用中括号[]包起来,各个值逗号隔开。KV和列表可以嵌套,例如:

{"name": "小明", "age": 10, "friends": ["小红", "小光"]}

题外话,这个JSON跟Python里面的字典比较像,但Python比较有意思是不可变的元素都能作为key

# 数字作为key {1: "冠军", 2:"殿军", 3:"季军"} # 元组作为key {(1, "TOM"): {"count": 1, ...}, (5, "Lily"):{"count": 10, ...}...}

Python处理JSON配置

python处理JSON就更简单了。系统自动的json库即可,json.load可以直接从文件中加载JSON配置并返回,json.loads也可以从字符串中加载。返回的都是Python中的字典(dict)或者列表(list)类型。

一般为了使用方便,还会将字典作为入参,生成预先定义好的数据结果对象,例如pydantic.BaseMode对象。

如下例,第1行开始定义Menu结构体,第22行直接从文件中读取JSON配置(1个列表嵌套配置),第24行根据json.load加载出来之后遍历的字典,来赋值生成Menu对象,指定类型和结构的配置变量,方便程序其他模块代码调用。

class Menu(BaseModel): uri: str = Field(default="", title="菜单的uri",) name: str = Field(default="未知名称", title="菜单展示的名称") description: Optional[str] = Field(default="描述", title="描述") is_hide: int = Field(default=0, title="是否隐藏",) query: KsshPramas = Field(default=None, title="是否隐藏") def __init__(self, **kwargs): kwargs['uri'] = str(kwargs['uri']).lower() super().__init__(**kwargs) class MenuList(BaseModel): menu_list: List[Menu] = Field(default=[], title="用户可访问的菜单配置", ) current_json = "json文件路径" with open(current_json, "r", encoding="utf8") as f: conf_menu = MenuList(menu_list=[]) # json.load从文件中加载,并被遍历 for menu in json.load(f): # 实例化成Menu对象 m = Menu(**menu) if m.is_hide: continue conf_menu.menu_list.append(m)

INI和JSON选取建议

INI配置感觉更面向用户,JSON配置更显臃肿复杂。根据他们各自的特点,我们实际生产环境中,INI用于环境配置等,由用户或者运维配置,而JSON配置则多应用于发布或者较少改动的软件参数配置,由较专业人员完成配置

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页