1.前言

在实际项目中,经常会接触到各种各样的配置文件,它可以增强项目的可维护性

常用配件文件的处理方式,包含:JSON、ini / config、YAML、XML 等

本篇文章,我们将聊聊 Python 数据处理全家桶之配置文件大总结

​2.JSON

Python 内置了 JSON 模块,可以非常方便操作 JSON 数据

常见的 4 个方法分别是:

  • json.load(json_file)

    解析 JSON 文件,转换为 Python 中对应的数据类型

  • json.loads(json_string)

    解析 JSON 格式的字符串,结果为 Python 中的字典

  • json.dump(python_content,file_path)

    将 Python 数据,包含:dict、list 写入到文件中

  • json.dumps(python_dict)

    将 Python 中 dict 转为 JSON 格式的字符串

以下面这段 JSON 配置文件为例:

#config.json
{
"mysql": {
"host": "198.0.0.1",
"port": 3306,
"db": "xh",
"username": "root",
"password": "123456",
"desc": "Mysql配置文件"
}
}

1、读取配置文件

读取配置文件有两种方式,分别是:

使用 json.load() 直接读取配置文件

或者,先读取配置文件中的内容,然后使用 json.loads() 转换为 Python 数据类型

需要指出的是,面对复杂层级的 JSON 配置文件,可以利用 jsonpath 进行读取;jsonpath 类似于 xpath,可以通过正则表达式快速读取数据

import json

def read_json_file(file_path):
"""
读取json文件
:param file_path:
:return:
"""
with open(file_path, 'r', encoding='utf-8') as file: # 读取方式二选一
# 方式一
result = json.load(file) # 方式二
# result = json.loads(file.read()) # 解析数据
host_mysql = result['mysql']['host']
port_mysql = result['mysql']['port']
db = result['mysql']['db'] print('Mysql地址:', host_mysql, ",端口号:", port_mysql, ",数据库:", db)

return result

2、保存配置文件

使用 json 中的 json.dump() 方法,可以将一个字典写入到 JSON 文件中

def write_content_to_json_file(output_file, content):
"""
写入到json文件中
:param output_file:
:param content:
:return:
"""
with open(output_file, 'w') as file:
# 写入到文件中
# 注意:为了保证中文能正常显示,需要设置ensure_ascii=False
json.dump(content, file, ensure_ascii=False) content_dict = {
'mysql': {
'host': '127.0.0.1',
'port': 3306,
'db': 'xh',
'username': 'admin',
'password': '123456',
'desc': 'Mysql数据库'
}
} write_content_to_json_file('./output.json', content_dict)

3、修改配置文件

如果需要修改配置文件,只需要先从配置文件中读出内容,然后修改内容,最后将修改后的内容保存的配置文件中即可

def modify_json_file():
"""
修改json配置文件
:return:
"""
result = read_json_file('./config.json') # 修改
result['mysql']['host'] = '198.0.0.1' write_content_to_json_file('./config.json', result)

3.ini/config

ini 配置文件和 config 配置文件的解析方式类似,仅仅是文件后缀不一致

这里我们以 ini 配置文件为例

# config.ini
[mysql]
host = 139.199.1.1
username = root
password = 123456
port = 3306

ini 文件由 3 部分组成,分别是:节点(Section)、键(Key)、值(Value)

常见的 Python 处理 ini 文件有两种方式,包含:

  • 使用内置的 configparser 标准模块

  • 使用 configobj第三方依赖库

我们先来看看内置的 configparser 模块

3.1.1 读取配置文件

实例化一个 ConfigParser 解析对象,使用 read() 方法读取 ini 配置文件

from configparser import ConfigParser

# 实例化解析对象
cfg = ConfigParser() # 读取ini文件内容
cfg.read(file_path)

使用 sections()函数,可以获取所有的节点列表

# sections() 得到所有的section,并以列表的形式返回
sections = cfg.sections()
print(sections)

要获取某一个节点下的所有键,可以使用 options(section_name) 函数

# 获取某一个区域的所有key
# cfg.options(section_name)
keys = cfg.options('mysql')
print(keys)

通过 items(section_name) 函数,可以获取某一个节点下的所有键值对

# 获取某一个区域下的键值对
items = cfg.items("mysql")
print(items)

如果要获取某一个节点下,某一个键下的值,使用 get(section_name,key_name) 函数即可

# 读取某一个区域下的某一个键值
host = cfg.get("mysql", "host")
print(host)

3.1.2 写入配置文件

和读取配置文件类似,需要先实例化一个 ConfigParser 解析对象

首先,使用 add_section(section_name) 函数添加一个节点

# 加入节点和键值对
# 添加一个节点
cfg.add_section("redis")

然后,就可以使用 set(section_name,key,value) 函数往某一个节点添加键值对

# 往节点内,添加键值对
cfg.set("redis", "host", "127.0.0.1")
cfg.set("redis", "port", "12345")

最后,使用 write() 函数写入到配置文件中去

# 写入到文件中
cfg.write(open('./raw/output.ini', 'w'))

3.1.3 修改配置文件

修改配置文件的步骤是,读取配置文件,然后通过 set(section_name,key,value) 进行修改操作,最后使用 write() 函数写入到文件中即可

def modify_ini_file(file_path):
"""
修改ini文件
:return:
"""
cfg.read(file_path) cfg.set("mysql", "host", "139.199.11.11") # 写入
cfg.write(open(file_path, "w"))

接着,我们聊聊使用 configobj 操作 ini 配置文件的流程

首先安装 configobj 依赖库

# 依赖
# pip3 install configobj

3.2.1 读取配置文件

直接将 ini 配置文件路径作为参数,使用 ConfigObj 类构造一个对象

from configobj import ConfigObj

# 实例化对象
config = ConfigObj(file_path, encoding='UTF8')

查看源码可以发现,ConfigObj 是 Section 节点的子类,而 Section 是 Dict 字典的子类

所以,可以直接通过键名 Key 获取节点和键值

# <class 'configobj.ConfigObj'>
print(type(config)) # <class 'configobj.Section'>
print(type(config['mysql'])) # 节点
print(config['mysql']) # 某一个键对应的值
print(config['mysql']

3.2.2 修改配置文件

只需要读取配置文件,然后直接修改 ConfigObj 对象,最后使用 write() 方法,即可以达到修改配置文件的目的

def modify_ini_file(file_path):
"""
修改ini文件
:param file_path:
:return:
"""
# 读取配置文件
config = read_ini_file(file_path) # 直接修改
config['mysql']['host'] = '139.199.1.1' # 删除某个键值对
try:
del config['mysql']['db']
except Exception as e:
print('键不存在')
pass # 写入
config.write()

3.2.3 写入配置文件

写入配置文件,首先需要实例化一个 ConfigObj 对象,传入文件路径

然后,设置节点、针对节点设置键值对

最后,调用 write() 方法,写入到配置文件中

def write_to_ini_file(output):
"""
写入到ini文件中
:param output:
:return:
"""
config = ConfigObj(output, encoding='UTF8')
config['website'] = {}
config['website']['url'] = "www.baidu.com"
config['website']['name'] = "百度" # 保存
config.write()

4.YAML

Python 操作 YAML 文件,常见的 2 种方式分别是:pyyaml、ruamel.yaml

使用 pip 安装依赖

# 安装依赖
# 方式一
pip3 install pyyaml # 方式二
pip3 install ruamel.yaml

下面以一个简单的 YAML 配置文件为例,通过两种方式进行说明

# 水果
Fruits:
# 苹果
- Apple:
name: apple
price: 1
address: 广东
# 桔子
- Orange:
name: orange
price: 3
address: 湖南
# 香蕉
- Banana:
name: banana
price: 2
address: 海南

我们先来看看 pyyaml

4.1.1 读取配置文件

首先,读取配置文件,使用 yaml.safe_load() 加载数据,获取的数据类型是字典

import yaml

with open(file_path, "r") as file:
data = file.read() # safe_load() 读取配置文件
# 结果数据类型:dict
result = yaml.safe_load(data) print(result)

接着,就可以通过 YAML 配置文件的层级关系,获取键值

# 3、获取yaml中的值
name = result['Fruits'][0]['Apple']['name']
price = result['Fruits'][0]['Apple']['price']
address = result['Fruits'][0]['Apple']['address']
print("名称:", name, ",price:", price, ",address:", address)

4.1.2 写入配置文件

使用 YAML 中的 dump() 方法,可以将一个字典写入到 YAML 配置文件中

需要注意的是,为了保证中文写入能正常显示,需要配置 allow_unicode=True

def write_to_yaml_file(content, file_path):
"""
写入到yaml文件中
:param content:
:param file_path:
:return:
""" # 写入到文件中
with open(file_path, 'w', encoding='utf-8') as file:
yaml.dump(content, file, default_flow_style=False, encoding='utf-8', allow_unicode=True) # 定义一个字典
content = {
"websites": [{"baidu": {'url': "www.baidu.com", 'name': '百度', "price": 100}},{"alibaba": {'url': "www.taobao.com", 'name': '淘宝', "price": 200}},{"tencent": {'url': "www.tencent.com", 'name': '腾讯', "price": 300}},]
} write_to_yaml_file(content, "./raw/new.yaml")

4.1.3 修改配置文件

和修改 ini 文件类型,先读取配置文件,然后修改字典中的内容,最后使用上面的写入方法,即可以达到修改配置文件的目的

def modify_yaml_file():
"""
修改yaml文件
:return:
"""
content = read_yaml_file('./raw/norm.yaml')
print(content) # 修改dict
content['Fruits'][0]['Apple']['price'] = 10086 # 重新写入到一个新的yaml文件中
write_to_yaml_file(content, './raw/output.yaml')

接着,我们来聊聊使用 ruamel 操作 YAML 配置文件的流程

ruamel 是 pyyaml 的衍生版本,在传统 pyyaml 的基础上,增加了 RoundTrip 模式,保证 YAML 配置文件的读写顺序一致

所以,在读取、修改、写入方式上和 pyyaml 类似

4.2.1 读取配置文件

from ruamel import yaml

def read_yaml_file(file_path):
"""
读取yaml文件
:param file_path:
:return:
"""
with open(file_path, 'r', encoding='utf-8') as file:
data = file.read() # 解析yaml文件
# 类型:ordereddict
result = yaml.load(data, Loader=yaml.RoundTripLoader) name = result['Fruits'][0]['Apple']['name']
price = result['Fruits'][0]['Apple']['price']
address = result['Fruits'][0]['Apple']['address']
print("名称:", name, ",price:", price, ",address:", address) return result

4.2.2 写入配置文件

def write_to_yaml_file(filepath, data):
"""
写入到yaml文件中
:param filepath:
:param data:
:return:
"""
with open(filepath, 'w', encoding='utf-8') as file:
yaml.dump(data, file, Dumper=yaml.RoundTripDumper, allow_unicode=True)

4.2.3 修改配置文件

def modify_yaml_file():
"""
修改yaml文件
:return:
"""
content = read_yaml_file('./raw/norm.yaml') print(content) # 修改dict
content['Fruits'][0]['Apple']['price'] = 10086 # 重新写入到一个新的yaml文件中
write_to_yaml_file('./raw/output.yaml', content)

5.XML

XML 作为一种标记语言,被用来设计存储和传输数据,很多项目经常使用 XML 作为配置文件和数据传输类型

Python 内置的 xml 模块 可以很方便地处理 XML 配置文件

以下面这段配置文件为例:

<?xml version="1.0" encoding="utf-8"?>
<dbconfig>
<mysql>
<host>127.0.0.1</host>
<port>3306</port>
<dbname>test</dbname>
<username>root</username>
<password>4355</password>
</mysql>
</dbconfig>

首先,使用 xml.dom.minidom.parser(file_path) 解析配置文件,利用 documentElement 属性获取 XML 根节点

import xml.dom.minidom

# 读取配置文件
dom = xml.dom.minidom.parse("./raw.xml") # 利用 documentElement 属性获取 XML 根节点
# 根节点
root = dom.documentElement

接着,使用 getElementsByTagName(tag_name) 方法,获取某一节点

# 获取mysql节点
node_mysql = root.getElementsByTagName('mysql')[0]

最后,使用 childNodes 属性,遍历节点的子 Node 节点,获取节点的名称和值

# 遍历子节点,获取名称和值
for node in node_mysql.childNodes:
# 节点类型
# 1:Element
# 2:Attribute
# 3:Text
# print(node.nodeType)
if node.nodeType == 1:
print(node.nodeName, node.firstChild.data)

6.最后

到此,Python 数据全家桶以全部完结!

我已经将文中全部源码上传到后台,关注公众号「 AirPython 」后回复「 dball 」即可获得全部源码

如果你觉得文章还不错,请大家 点赞、分享、留言下,因为这将是我持续输出更多优质文章的最强动力!

推荐阅读

聊聊 Python 数据处理全家桶(Mysql 篇)

聊聊 Python 数据处理全家桶(Sqlite 篇)

聊聊 Python 数据处理全家桶(Redis 篇)

聊聊 Python 数据处理全家桶(Memc 篇)

聊聊 Python 数据处理全家桶(Mongo 篇)

最全总结 | 聊聊 Python 数据处理全家桶(配置篇)的更多相关文章

  1. 最全总结 | 聊聊 Python 数据处理全家桶(PgSQL篇)

    1. 前言 大家好,我是安果! Python 数据处理全家桶,截止到现在,一共写过 6 篇文章,有兴趣的小伙伴可以去了解一下! 最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇) 最全 ...

  2. 最全总结 | 聊聊 Python 数据处理全家桶(Sqlite篇)

    1. 前言 上篇文章 聊到 Python 处理 Mysql 数据库最常见的两种方式,本篇文章继续说另外一种比较常用的数据库:Sqlite Sqlite 是一种 嵌入式数据库,数据库就是一个文件,体积很 ...

  3. 最全总结 | 聊聊 Python 数据处理全家桶(Redis篇)

    1. 前言 前面两篇文章聊到了 Python 处理 Mysql.Sqlite 数据库常用方式,本篇文章继续说另外一种比较常用的数据存储方式:Redis Redis:Remote Dictionary ...

  4. 最全总结 | 聊聊 Python 数据处理全家桶(Memcached篇)

    1. 前言 本篇文章继续继续另外一种比较常用的数据存储方式:Memcached Memcached:一款高性能分布式内存对象缓存系统,通过 内存缓存,以减少数据库的读取,从而分担数据库的压力,进而提高 ...

  5. 最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇)

    1. 前言 在爬虫.自动化.数据分析.软件测试.Web 等日常操作中,除 JSON.YAML.XML 外,还有一些数据经常会用到,比如:Mysql.Sqlite.Redis.MongoDB.Memch ...

  6. 最全总结 | 聊聊 Python 办公自动化之 Excel(中)

    1. 前言 上一篇文章中,我们聊到使用 xlrd.xlwt.xlutils 这一组合操作 Excel 的方法 最全总结 | 聊聊 Python 办公自动化之 Excel(上) ​本篇文章将继续聊另外一 ...

  7. 最全总结 | 聊聊 Python 办公自动化之 Excel(上)

    1. 前言 在我们日常工作中,经常会使用 Word.Excel.PPT.PDF 等办公软件 但是,经常会遇到一些重复繁琐的事情,这时候手工操作显得效率极其低下:通过 Python 实现办公自动化变的很 ...

  8. 最全总结 | 聊聊 Python 办公自动化之 Excel(下)

    1. 前言 前面谈到 Python 处理 Excel 文件最常见的两种方式,即:xlrd/xlwt.openpyxl ​其中, xlrd/xlwt 这一组合,xlrd 可以负责读取数据,而 xlwt ...

  9. 最全总结 | 聊聊 Python 办公自动化之 Word(上)

    1. 前言 日常自动化办公中,使用 Python 真的能做到事半功倍! 在上一个系列中,我们对 Python 操作 Excel 进行了一次全面总结 最全总结 | 聊聊 Python 办公自动化之 Ex ...

随机推荐

  1. File类 -《学堂在线》

    File类的作用 ·创建.删除文件: ·重命名文件:判断文件的读写权限及是否存在: ·设置和查询文件的最近修改时间等: ·构造文件流可以使用File类的对象作为参数. //: FileTester.j ...

  2. 3点带你快速学会Selenium工具的使用

    (一)Selenium IDE Firefox的一个插件,有助于我们理解测试框架.在附加组件里搜索下载,一般搜的结果里前几个都不是,得点那个查看更多才行,找到这个: 安装以后浏览器工具栏会有: 安装好 ...

  3. 5分钟快速学会xpath定位

    今天我们先来和大家说一下appium,首先教大家如何定位xpath,五分钟即可学会:例:现在我想定位下面这个登录按钮: xpath该怎么写呢? 先不管三七二十几,先写//,然后找你要定位元素最近的可以 ...

  4. Log4Net + Log4Mongo 将日志记录到MongoDb中

    实现: 将日志保存在MongoDb中: 自定义日志字段: 日志按照日期拆分集合: 第一部分:将日志保存在MongoDb中 新建控制台程序Log4MongoDemo 通过NuGet安装Log4Net ( ...

  5. 利用 Python 写个七夕表白神器

    今天是七夕节,相比于现代人自创的 502,不对是 520,七夕才是中国传统意义上的情人节,本文分享几个 Python 表白程序,情侣可以现学现用,单身的话也可以先收藏一下,说不定下次就用上了. 很多人 ...

  6. Labview学习之路(十)文本文件再次写入不覆盖

  7. 避免nullpointer 空指针

    来自知乎: 一般在服务器返回的数据上我们会做数据合法性检测,所以在api文档上需要注明字段的取值范围,然后客户端根据这个去做数据检测,缺段就直接走数据错误的流程,这个很大程度上避免了不少nullpoi ...

  8. 初级知识点二——C#值传递

    C#中有值传递和引用传递,这个东西一直有点儿绕,今天花点儿时间来把这个事情搞清楚. 传递值类型的参数 值类型的变量,是直接包含其数据的.实际上,在向方法传递一个值类型变量,其实就意味着向方法传递了一个 ...

  9. 解决Oracle在win10 64使用plsql 无法显示表

    将当前用户切换至所有用户,然后再切换至当前用户,问题解决 图中sql也可查询出当前库中存在的表: select object_name from user_objects where lower(ob ...

  10. promise 基本流程