文章目录
- # 字符串 (通常不需要引号,除非有特殊字符) name: John Doe company: “CSDN & Co.” # 包含特殊字符&,建议加引号 title: This is a title # 数字 age: 29 score: 89.5 # 布尔值 is_active: true # 或 True, TRUE is_admin: false # 或 False, FALSE # 空值 salary: null # 或 Null, NULL, ~ # 日期和时间 date: 2023-10-27 datetime: 2023-10-27T15:30:00+08:00
- 列表和字典可以自由组合,形成复杂的数据结构。 # 一个列表中包含多个字典 users: – name: John id: 1 hobbies: – reading – hiking – name: Jane id: 2 hobbies: – gaming – cooking # 一个字典中某个值是列表 server: ip: 192.168.1.1 ports: – 80 – 443 – 8080
- YAML 还支持一些高级特性,如锚点 & 和别名 * 用于复用代码块,以及多行字符串。 # 锚点(&)和别名(*) – 避免重复 defaults: &defaults adapter: postgres host: localhost development: <<: *defaults # 合并defaults的内容 database: dev_db test: <<: *defaults database: test_db # 多行字符串 description: | This is a long text that spans multiple lines. # 保留换行符 signature: > This will fold into a single line. # 将换行折叠为空格
- 通过 pip 即可安装: pip install pyyaml
- 将 Python 对象(字典、列表)写回 YAML 文件。 import yaml # 要写入的 Python 数据 data_to_write = { ‘project’: ‘Awesome Project’, ‘author’: ‘CSDN Blogger’, ‘tags’: [‘python’, ‘tutorial’, ‘yaml’], ‘config’: { ‘timeout’: 30, ‘retries’: 3 } } # 写入文件 with open(‘output.yml’, ‘w’, encoding=’utf-8′) as f: # safe_dump() 同样比 dump() 更安全 # allow_unicode: 确保中文等字符正确显示 # indent: 指定缩进空格数,让文件更美观 yaml.safe_dump( data_to_write, f, allow_unicode=True, indent=2 # 可选,使用2空格缩进,更美观 ) # 也可以直接生成一个YAML字符串 yaml_string = yaml.safe_dump(data_to_write, allow_unicode=True) print(yaml_string) 运行后生成的 output.yml 文件内容如下: author: CSDN Blogger config: retries: 3 timeout: 30 project: Awesome Project tags: – python – tutorial – yaml
目录
- 1. 引言:为什么选择 YAML?
- 2. YAML 基础语法
- 2.1 基本数据类型
- 2.2 复合数据类型
- 列表 (List/Array)
- 字典 (Map/Dictionary)
- 2.3 复杂结构嵌套
- 2.4 高级特性(可选)
- 3. Python 操作 YAML 文件
- 3.1 安装 PyYAML
- 3.2 读取 YAML 文件 (yaml.safe_load())
- 3.3 写入 YAML 文件 (yaml.safe_dump())
- 4. 实战:一个完整的配置管理示例
- 5. 安全警告与最佳实践
- 6. 常见错误
- 总结
在现代软件开发中,配置管理是至关重要的一环。告别硬编码,拥抱灵活的配置文件,YAML 正是为此而生的理想选择之一。
在 Python 项目中,我们经常需要配置数据库连接、API 密钥、路径设置等参数。如果将这些信息直接写在代码里(硬编码),会带来极大的安全隐患和维护成本。常见的配置文件格式有 .ini, .json, .xml 和 .yaml/.yml。
与其他格式相比,YAML 的优势在于:
- 可读性极高:采用清晰的缩进结构,类似于 Python,即使非技术人员也能轻松理解。
- 简洁的语法:不需要像 JSON 那样充斥大量的括号和引号,也不像 XML 那样冗余。
- 强大的功能:支持注释、引用、复杂数据类型(列表、字典),甚至可以实现数据序列化。
- 语言无关:作为一种数据格式,它被多种编程语言广泛支持。
它特别适合用于:配置文件、数据序列化、持续集成/部署 (CI/CD) 管道(如 GitHub Actions, Docker Compose, Kubernetes)。
YAML 的核心思想是使用缩进来表示层级关系,禁止使用 Tab 键,只能使用空格。
# 字符串 (通常不需要引号,除非有特殊字符)
name: John Doe
company: "CSDN & Co." # 包含特殊字符&,建议加引号
title: This is a title
# 数字
age: 29
score: 89.5
# 布尔值
is_active: true # 或 True, TRUE
is_admin: false # 或 False, FALSE
# 空值
salary: null # 或 Null, NULL, ~
# 日期和时间
date: 2023-10-27
datetime: 2023-10-27T15:30:00+08:00
使用短横线 - 加一个空格来表示列表项。
fruits: - Apple - Banana - Orange # 行内写法 (类似JSON数组) colors: [red, blue, green]
使用 key: value 的形式表示。
person:
name: Alice
age: 25
address: Beijing
# 行内写法 (类似JSON对象)
coordinates: { x: 12.5, y: -7.2 }
列表和字典可以自由组合,形成复杂的数据结构。
# 一个列表中包含多个字典
users:
- name: John
id: 1
hobbies:
- reading
- hiking
- name: Jane
id: 2
hobbies:
- gaming
- cooking
# 一个字典中某个值是列表
server:
ip: 192.168.1.1
ports:
- 80
- 443
- 8080
YAML 还支持一些高级特性,如锚点 & 和别名 * 用于复用代码块,以及多行字符串。
# 锚点(&)和别名(*) - 避免重复 defaults: &defaults adapter: postgres host: localhost development: <<: *defaults # 合并defaults的内容 database: dev_db test: <<: *defaults database: test_db # 多行字符串 description: | This is a long text that spans multiple lines. # 保留换行符 signature: > This will fold into a single line. # 将换行折叠为空格
Python 操作 YAML 文件主要使用第三方库 PyYAML。
通过 pip 即可安装:
pip install pyyaml
假设我们有一个 config.yml 文件:
# config.yml
database:
host: localhost
port: 3306
username: admin
password: secret123
db_name: my_app
logging:
level: INFO
file: /var/log/my_app.log
rotation: 5
features:
enable_upload: true
allowed_file_types:
- .jpg
- .png
- .pdf
在 Python 中读取这个文件:
import yaml
import pathlib
# 推荐使用 pathlib 处理路径
config_path = pathlib.Path('config.yml')
# 使用 safe_load() 而不是 load() 以避免安全风险!
with config_path.open('r', encoding='utf-8') as f:
config_data = yaml.safe_load(f)
# 现在可以像操作普通字典一样访问配置
print(config_data['database']['host']) # 输出: localhost
print(config_data['features']['enable_upload']) # 输出: True
# 获取日志配置
log_level = config_data['logging']['level']
print(f"日志级别是: {log_level}")
将 Python 对象(字典、列表)写回 YAML 文件。
import yaml
# 要写入的 Python 数据
data_to_write = {
'project': 'Awesome Project',
'author': 'CSDN Blogger',
'tags': ['python', 'tutorial', 'yaml'],
'config': {
'timeout': 30,
'retries': 3
}
}
# 写入文件
with open('output.yml', 'w', encoding='utf-8') as f:
# safe_dump() 同样比 dump() 更安全
# allow_unicode: 确保中文等字符正确显示
# indent: 指定缩进空格数,让文件更美观
yaml.safe_dump(
data_to_write,
f,
allow_unicode=True,
indent=2 # 可选,使用2空格缩进,更美观
)
# 也可以直接生成一个YAML字符串
yaml_string = yaml.safe_dump(data_to_write, allow_unicode=True)
print(yaml_string)
运行后生成的 output.yml 文件内容如下:
author: CSDN Blogger config: retries: 3 timeout: 30 project: Awesome Project tags: - python - tutorial - yaml
让我们创建一个更实际的例子,模拟一个应用的配置加载过程。
项目结构:
my_app/ ├── config.yml └── app.py
1. 创建配置文件 config.yml
# config.yml app: name: My Python Application version: 1.0.0 environment: development # production / staging database: url: mysql+pymysql://user:pass@localhost:3306/dev_db pool_size: 5 echo_sql: false api: endpoint: https://api.example.com/v1 timeout_seconds: 10 retries: 2 api_key: YOUR_API_KEY_HERE # 切记不要在代码中提交真实密钥! logging: level: DEBUG format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
2. 创建主程序 app.py
# app.py
import yaml
import pathlib
import logging
from typing import Dict, Any
def load_config(config_file: pathlib.Path) -> Dict[str, Any]:
"""加载YAML配置文件"""
if not config_file.exists():
raise FileNotFoundError(f"配置文件 {config_file} 未找到!")
with config_file.open('r', encoding='utf-8') as f:
config = yaml.safe_load(f)
return config
def setup_logging(logging_config: Dict[str, Any]):
"""根据配置设置日志"""
logging.basicConfig(
level=getattr(logging, logging_config['level']),
format=logging_config['format']
)
logging.info("日志系统初始化成功!")
def main():
# 1. 加载配置
try:
config = load_config(pathlib.Path('config.yml'))
except Exception as e:
print(f"加载配置失败: {e}")
return
# 2. 读取应用配置
app_config = config['app']
print(f"启动应用: {app_config['name']} (版本: {app_config['version']})")
# 3. 设置日志
setup_logging(config['logging'])
# 4. 模拟使用其他配置
db_url = config['database']['url']
api_endpoint = config['api']['endpoint']
# ... 这里可以继续初始化数据库连接、API客户端等 ...
logging.debug(f"数据库URL: {db_url}")
logging.info(f"API端点: {api_endpoint}")
logging.warning("这是一个警告信息!")
print("应用初始化完成,开始运行...")
if __name__ == "__main__":
main()
运行结果:
启动应用: My Python Application (版本: 1.0.0) 应用初始化完成,开始运行...
同时,在日志中你会看到相应的调试和信息输出。
-
始终使用 safe_load() 和 safe_dump():
yaml.load() 和 yaml.dump() 功能强大,但可以执行任意 Python 代码,如果加载来自不可信源的 YAML 文件,会带来严重的代码注入安全风险。safe_load() 和 safe_dump() 将其限制为仅加载标准的 YAML 标签,因此是绝对安全的选择。
-
敏感信息处理:
永远不要将真正的密码、API 密钥等敏感信息直接提交到代码仓库。应该:
- 使用环境变量(如
os.getenv('DB_PASSWORD'))。
- 或者使用
.env 文件并通过 python-dotenv 库加载,然后在 YAML 配置中通过变量引用。
- 专门的文件来管理密钥。
- 对.env文件和python-dotenv包的使用请参考我撰写的另一篇博文:python-dotenv:用.env储存系统变量并在Python3代码中调用
-
配置默认值和验证:
对于可选的配置项,应在代码中提供合理的默认值。可以使用像 Pydantic 或 marshmallow 这样的库来验证加载的配置数据结构是否正确,避免缺少必要的配置项导致运行时错误。
始终使用 safe_load() 和 safe_dump():yaml.load() 和 yaml.dump() 功能强大,但可以执行任意 Python 代码,如果加载来自不可信源的 YAML 文件,会带来严重的代码注入安全风险。safe_load() 和 safe_dump() 将其限制为仅加载标准的 YAML 标签,因此是绝对安全的选择。
敏感信息处理:
永远不要将真正的密码、API 密钥等敏感信息直接提交到代码仓库。应该:
- 使用环境变量(如
os.getenv('DB_PASSWORD'))。 - 或者使用
.env文件并通过python-dotenv库加载,然后在 YAML 配置中通过变量引用。 - 专门的文件来管理密钥。
- 对.env文件和python-dotenv包的使用请参考我撰写的另一篇博文:python-dotenv:用.env储存系统变量并在Python3代码中调用
配置默认值和验证:
对于可选的配置项,应在代码中提供合理的默认值。可以使用像 Pydantic 或 marshmallow 这样的库来验证加载的配置数据结构是否正确,避免缺少必要的配置项导致运行时错误。
- 一个从老版本转换为新版本时会遇到的问题:
TypeError: load() missing 1 required positional argument: 'Loader' in Google Colab

解决方案:将load()改为safe_load()1
-
python – TypeError: load() missing 1 required positional argument: ‘Loader’ in Google Colab – Stack Overflow ↩︎
TypeError: load() missing 1 required positional argument: 'Loader' in Google Colab

解决方案:将load()改为safe_load()1
python – TypeError: load() missing 1 required positional argument: ‘Loader’ in Google Colab – Stack Overflow ↩︎
到此这篇关于Python yaml格式配置文件操作实战的文章就介绍到这了,更多相关Python yaml格式配置文件内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Python3操作YAML文件格式方法解析
- python使用yaml格式文件的方法
- python处理 yaml 时保持输入输出格式一致的问题记录