pyyaml_include 2.x 版本使用说明
Pyyaml_include是PyYAML的一个扩展库, 允许在YAML文件中通过使用某种标签动态包含其他文件的内容。
之前一直使用的是1.x版本,今天新的项目需要重新安装pyyaml_include,发现版本升级了,原来的1.x的方法无法引用了就去官网查看。果然升级后的2.x版本不兼容1.x版本,并且pyyaml_include 2.x还引入了fsspec,使得yaml中可以包括http,sftp,s3等文件,于是就想分享一下pyyaml_include 2.x 版本的使用
PS:截止20250317 下载的最新版本是2.2,本次基于该版本介绍
PS:deepseek和豆包只能搜到1.x的使用方法,被迫去的官网找的资料,由此可见官网依旧是最可靠的信息来源
pyyaml_include 2.x 安装
pip3 install "pyyaml-include"
pyyaml_include 2.x 使用
常规用法
由于pyyaml_include 2.x还引入了fsspec,这说明yaml中可以包括http,sftp,s3等文件。但是本次只介绍yaml文件中包含yaml文件的情况,其他内容可自行到官网查看。
现有文件1.yml,2.yml,0.yml三个文件,使0.yml文件包含1.yml和2.yml文件中的内容
├── 0.yml
└── include.d
├── 1.yml
└── 2.yml
1.yml内容
name: "1"
2.yml内容
name: "2"
Step1: 将`yaml_include.constructor
注册到Pyyaml的Loader
类,并使用!inc
为tag,或任何以!
开头的tag作为标记
import yaml
import yaml_include
# add the tag 以“!inc”为tag
yaml.add_constructor("!inc", yaml_include.Constructor(base_dir='/your/conf/dir'))
# base_dir='/your/conf/dir') 该参数有默认值为None, yaml文件中包含yaml文件中可以不是使用
Step2: 0.yml中使用!inc
tag PS:被包含的1.yml和2.yml文件的路径必须是绝对路径
# 这个文件路径必须是绝对路径
file1: !inc include.d/1.yml
# 同上
file2: !inc include.d/2.yml
Step3: 在Python程序中加载0.yaml
with open('0.yml') as f:
data = yaml.full_load(f)
print(data)
执行结果:
{'file1': {'name': '1'}, 'file2': {'name': '2'}}
step4:如果想要取消对以“!inc”为tag的注册
del yaml.Loader.yaml_constructors["!inc"]
del yaml.UnSafeLoader.yaml_constructors["!inc"]
del yaml.FullLoader.yaml_constructors["!inc"]
以字典形式包含
If 0.yml
was:
file1: !inc include.d/1.yml
file2: !inc include.d/2.yml
We'll get:
file1:
name: "1"
file2:
name: "2"
以序列形式包含
If 0.yml
was:
files:
- !inc include.d/1.yml
- !inc include.d/2.yml
We'll get:
files:
- name: "1"
- name: "2"
高级用法
通配符
文件名字可以包含shell风格的通配符。
文件名可以包含 Shell 风格的通配符(如 *
、?
)。通过通配符匹配到的文件加载的数据将会以序列的形式返回。也就是说,返回的是一个列表,列表的长度等于匹配到的文件数量
If 0.yml
was:
files: !inc include.d/*.yml
We'll get:
files:
- name: "1"
- name: "2"
-
当仅匹配到 1 个文件 时,列表的长度将为 1
-
当没有匹配到任何文件时,将返回一个 空列表
Pyyaml_include2.x支持 (匹配任意数量的字符)、?(匹配单个字符)和 [..](匹配范围内的字符)。我们不支持使用 ^ 进行模式否定。对于 (双星号)的匹配深度限制(maxdepth)仅在路径中首次出现的 ** 时生效
❗ 特别注意
在大型目录树或远程文件系统(如 S3、HTTP 等)中使用
**
模式可能会消耗大量时间。目前没有类似 惰性加载(lazy-load) 或 迭代处理 的方法。所有通过
**
模式匹配到的文件数据都会立即完全加载到内存中。如果匹配到大量或大文件,可能会需要大量的内存