Python轮子:pyyaml~yaml文件处理利器

原文链接:http://www.juzicode.com/python-module-yaml

PyYAML是Python的YAML处理库,支持YAML 1.1规范,提供人性化的数据序列化与反序列化功能,适用于配置文件、数据交换和持久化存储场景。

应用场景

  • 应用配置管理
  • 测试数据驱动
  • API响应数据解析
  • Docker Compose文件处理
  • 数据科学管道配置
  • 跨语言数据交换

安装与导入

# juzicode.com/VX公众号:juzicode
pip install pyyaml
import yaml

使用方法

1. YAML字符串解析

# juzicode.com/VX公众号:juzicode
import yaml

data = """
name: 桔子代码
services:
  - web:
      port: 8080
      image: nginx:latest
  - db:
      type: mysql
      version: 8.0
"""
parsed = yaml.safe_load(data)
print(f"服务数量: {len(parsed['services'])}")
print(f"数据库版本: {parsed['services'][1]['db']['version']}")

运行结果:)

服务数量: 2
数据库版本: 8.0

2. 文件读写操作

# juzicode.com/VX公众号:juzicode
import yaml
import tempfile
import os

config = {
    'logging': {
        'level': 'INFO',
        'file': '/var/log/app.log',
        'rotate': {'max_size': '10MB', 'backup': 5}
    }
}

# 写入临时文件
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
    yaml.safe_dump(config, f)
    tmp_path = f.name

# 读取验证
with open(tmp_path) as f:
    loaded = yaml.safe_load(f)
    print(f"日志级别: {loaded['logging']['level']}")
    
os.unlink(tmp_path)

运行结果:

日志级别: INFO

3. 多文档处理

# juzicode.com/VX公众号:juzicode
import yaml

multi_doc = '''---
- name: 配置A
  value: 100
---
- name: 配置B
  value: 200
'''

docs = list(yaml.safe_load_all(multi_doc))
print(f"文档数量: {len(docs)}")
print(f"第二个文档值: {docs[1]}")
print(f"第二个文档值: {docs[1][0]['value']}")

运行结果:

文档数量: 2
第二个文档值: [{'name': '配置B', 'value': 200}]
第二个文档值: 200

4. 锚点与别名

# juzicode.com/VX公众号:juzicode
import yaml

data = """
base: &base
  api_url: https://api.juzicode.com
  timeout: 30

production:
  <<: *base
  debug: false

development:
  <<: *base
  debug: true
"""

config = yaml.safe_load(data)
print("生产环境超时:", config['production']['timeout'])
print("开发模式调试:", config['development']['debug'])

运行结果:

生产环境超时: 30
开发模式调试: True

5. 安全加载配置

# juzicode.com/VX公众号:juzicode
import yaml

dangerous_yaml = "!!python/object/apply:os.system ['ls -la']"
try:
    yaml.safe_load(dangerous_yaml)
except yaml.YAMLError as e:
    print(f"安全拦截: {str(e)}")

运行结果:

安全拦截: could not determine a constructor for the tag 'tag:yaml.org,2002:python/object/apply:os.system'

6. 与JSON互转

# juzicode.com/VX公众号:juzicode
import yaml
import json

data = {
    'name': 'example',
    'features': ['readble',  'simple']
}

yaml_str = yaml.safe_dump(data)
json_str = json.dumps(yaml.safe_load(yaml_str))

print("YAML格式:\n", yaml_str)
print("转换JSON:", json_str)

运行结果:

YAML格式:
 features:
- readble
- simple
name: example

转换JSON: {"features": ["readble", "simple"], "name": "example"}

7. 自定义标签

# juzicode.com/VX公众号:juzicode
import yaml

def upper_constructor(loader, node):
    return node.value.upper()

yaml.add_constructor('!upper', upper_constructor)

data = "message: !upper 'hello world'"
result = yaml.load(data, Loader=yaml.FullLoader)
print("转换结果:", result['message'])

运行结果:

转换结果: HELLO WORLD

总结

PyYAML为数据序列化提供高效解决方案:

  • 支持复杂数据结构表达
  • 提供安全加载机制
  • 优秀的可读性与简洁性
  • 强大的跨语言兼容能力

注意事项:

  • 处理用户输入时始终使用safe_load
  • 注意缩进和格式的严格性
  • 复杂类型转换需充分测试

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注