yaml文件写法和加载(1)
yaml 是专门用来写配置文件的语言,个人认为比yaml比json格式更方便。在Python中,使用PyYAML库来处理YAML文件是一种常见的做法。YAML(YAML Ain’t Markup Language)是一种数据序列化格式,它以。
·
文章目录
yaml 是专门用来写
配置文件
的语言,个人认为比
yaml比json
格式更方便。在Python中,使用
PyYAML
库来处理YAML文件是一种常见的做法。YAML(YAML Ain’t Markup Language)是一种数据序列化格式,它以
易于阅读的方式表示数据结构,如哈希表、列表、标量等。
1. yaml 文件的写法
1.1 YAML语法基础
大小写敏感
缩进
:YAML使用空格进行缩进,通常是两个空格,不要使用制表符(tab键)。井号(#)
:用于添加注释。短横线(-
):用于列表的开始。冒号(:)
:用于键值对的分隔。- 相同层级的元素左对齐
- 字符串可以不用引号标注
1.2 yaml的安装
pip install pyyaml
1.3 案例
案例1
test.yaml
的内容如下:
# 这是一个注释
person:
name: John Doe
age: 30
skills:
- Python
- YAML
- Linux
is_employee: true
- 加载
test.yaml
import yaml
with open('test.yaml', 'r') as file:
try:
data = yaml.safe_load(file)
print(data)
except yaml.YAMLError as exc:
print(exc)
>> {'person': {'name': 'John Doe', 'age': 30, 'skills': ['Python', 'YAML', 'Linux']}, 'is_employee': True}
可以看出-
加一个空格,表示列表;:
用于键值对的分隔
案例2
- 列表中嵌套字典
-
name: 吴彦祖
age: 21
-
A: apple
- 读取yaml文件
import yaml
with open('test.yaml', 'r') as file:
try:
data = yaml.safe_load(file)
print(data)
except yaml.YAMLError as exc:
print(exc)
>> [{'name': '吴彦祖', 'age': 21}, {'A': 'apple'}]
案例3
TASKS:
- arrow
- crosswalk
- lane
- stopline
EVALUATION:
- name: LaneBEVEvaluator
interp_interval: 0.1
filter_region: [100, 5, 15, -15, 10, -10]
filter_ignore: False
# match_distance: [0.6, 0.6, 0] # xy, xz, rv
match_distance: [1, 1, 0] # xy, xz, rv
match_attribute: [road_curb, lane_type.color, lane_type.dashed, lane_type.shape]
chamfer_config:
decay_ratio: 0
region_range: [100, 5, 15, -15, 10, -10]
step: 1
use_common_dt_gt: True
keep_ratio: 0.9
mode: d<->g
eval_attributes: {
road4: {loc_type: [right1, left2, left1, right2]},
road2: {loc_type: [right1, left1]},
road_curb: {road_curb: [1]},
water_barrier: [{shuima: [1]}, {water_barrier: [1]}],
yellow_line: {lane_type.color: [yellow]},
white_line: {lane_type.color: [white]},
dotted_line: {lane_type.dashed: [dotted]},
solid_line: {lane_type.dashed: [solid]},
single_line: {lane_type.shape: [single]},
double_line: {lane_type.shape: [double]},
single_white_dotted_line: {
lane_type.shape: [single],
lane_type.color: [white],
lane_type.dashed: [dotted]
},
single_white_solid_line: {
lane_type.shape: [single],
lane_type.color: [white],
lane_type.dashed: [solid]
},
road4_white: {
lane_type.color: [white],
loc_type: [right1, left2, left1, right2]
},
road4_yellow: {
lane_type.color: [yellow],
loc_type: [right1, left2, left1, right2]
}
}
eval_threshold: 0.3
- name: StoplineBEVEvaluator
interp_interval: 0.1
filter_region: [100, 5, 15, -15, 10, -10]
filter_ignore: False
match_distance: [0.6, 0.6, 0] # xy, xz, rv
chamfer_config:
decay_ratio: 0
region_range: [100, 5, 15, -15, 10, -10]
step: 1
use_common_dt_gt: True
keep_ratio: 0.9
mode: d<->g
eval_threshold: 0.3
- name: CrosswalkBEVEvaluator
bev_region: [60, 0, 15, -15]
resolution: [0.15, 0.15]
- name: ArrowBEVEvaluator
categories: [forbid_left, forbid_right, forbid_through, forbid_turn,
guide_left, guide_right, guide_through, guide_turn]
bev_region: [60, 0, 15, -15]
resolution: [0.15, 0.15]
1.4 案例
yolov8 数据配置: DOTAv1.yaml
# Ultralytics YOLO 🚀, AGPL-3.0 license
# DOTA 1.0 dataset https://captain-whu.github.io/DOTA/index.html for object detection in aerial images by Wuhan University
# Documentation: https://docs.ultralytics.com/datasets/obb/dota-v2/
# Example usage: yolo train model=yolov8n-obb.pt data=DOTAv1.yaml
# parent
# ├── ultralytics
# └── datasets
# └── dota1 ← downloads here (2GB)
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../datasets/DOTAv1 # dataset root dir
train: images/train # train images (relative to 'path') 1411 images
val: images/val # val images (relative to 'path') 458 images
test: images/test # test images (optional) 937 images
# Classes for DOTA 1.0
names:
0: plane
1: ship
2: storage tank
3: baseball diamond
4: tennis court
5: basketball court
6: ground track field
7: harbor
8: bridge
9: large vehicle
10: small vehicle
11: helicopter
12: roundabout
13: soccer ball field
14: swimming pool
# Download script/URL (optional)
download: https://github.com/ultralytics/assets/releases/download/v0.0.0/DOTAv1.zip
```shell
>> {'path': '../datasets/DOTAv1', 'train': 'images/train', 'val': 'images/val', 'test': 'images/test', 'names': {0: 'plane', 1: 'ship', 2: 'storage tank', 3: 'baseball diamond', 4: 'tennis court', 5: 'basketball court', 6: 'ground track field', 7: 'harbor', 8: 'bridge', 9: 'large vehicle', 10: 'small vehicle', 11: 'helicopter', 12: 'roundabout', 13: 'soccer ball field', 14: 'swimming pool'}, 'download': 'https://github.com/ultralytics/assets/releases/download/v0.0.0/DOTAv1.zip'}
2. yaml 文件的读写
2.1 yaml.load() 和 yaml.safe_load()
在Python的PyYAML库中,yaml.safe_load()和yaml.load()都是用来解析YAML文件或字符串的函数,但它们之间存在一些关键的区别:
yaml.safe_load
- safe_load用于
安全地加载YAML
。它只加载YAML中的数据,而忽略任何自定义的YAML标签,这意味着它不会调用任何外部的标签解析器。 - 它被认为是
安全的
,因为它不会执行YAML中可能包含的任意代码
。 - 主要用于加载那些不包含自定义标签的YAML文件。
- 通常推荐使用yaml.safe_load
代码示例
import yaml
with open('data.yaml', 'r') as file:
try:
data = yaml.safe_load(file)
except yaml.YAMLError as exc:
print(exc)
yaml.load()
- load用于加载YAML,它允许加载YAML中的所有数据,包括自定义的YAML标签。
- 如果YAML文件包含自定义的标签,load将使用相应的加载器来解析这些标签,这可能导致执行YAML文件中定义的任意代码,因此存在安全风险。
- 通常不推荐使用load,除非你完全信任YAML文件的来源。
代码示例
import yaml
with open('data.yaml', 'r') as file:
try:
data = yaml.load(file)
except yaml.YAMLError as exc:
print(exc)
yaml.load()
默认使用FullLoader
,它会加载自定义标签。如果你使用-yaml.load(Loader=yaml.SafeLoader)
,即使文件包含自定义标签,也不会执行它们,但仍然会抛出异常。
安全性
- safe_load是安全的,因为它不会执行YAML中的自定义标签。
- load可能不安全,因为它允许执行YAML中的自定义标签。
功能
- safe_load的功能受限于不解析自定义标签,但它足以处理大多数标准的YAML数据。
- load提供了完整的YAML解析功能,包括自定义标签的解析。
使用场景
- 当你不确定YAML文件的来源或内容时,应该使用safe_load。
- 当你完全信任YAML文件的来源,并且需要解析自定义标签时,可以使用load。
- 手动动检查YAML文件的内容。自定义标签通常在YAML文件的开头以!符号开始,后面跟着标签名称。例如:
!!python/object/apply:mymodule.MyClass
2.2 yaml.dump() 和 yaml.safe_dump()
yaml.dump() 和 yaml.safe_dump() 都是 PyYAML 库中用于将 Python 对象序列化为 YAML 格式的字符串或写入到文件的函数。它们之间的主要区别在于安全性和功能:
yaml.dump()
- yaml.dump() 可以用来将 Python 对象序列化为 YAML 格式的字符串,并且可以写入到文件中。
- 它允许使用自定义的Dumper类,这意味着你可以自定义序列化的行为,比如添加自定义的代表或处理器。
- yaml.dump() 不是安全的,因为它允许执行 yaml 构造函数,这可能允许执行任意代码。
使用案例
import yaml
data = {'key': 'value'}
# 序列化为 YAML 格式的字符串
yaml_str = yaml.dump(data, default_flow_style=False)
print(yaml_str)
# 写入到文件
with open('data.yaml', 'w') as f:
yaml.dump(data, f, default_flow_style=False)
yaml.safe_dump()
- yaml.safe_dump() 与 yaml.dump() 功能类似,但它不允许执行自定义的 yaml 构造函数。
它是用来序列化那些不包含自定义代表的 Python 对象,因此被认为是安全的。 - yaml.safe_dump() 同样可以序列化对象到字符串或写入到文件,但它不支持自定义的Dumper类。
- 推荐使用
yaml.safe_dump()
代码示例
import yaml
data = {'key': 'value'}
# 安全地序列化为 YAML 格式的字符串
yaml_str = yaml.safe_dump(data, default_flow_style=False)
print(yaml_str)
# 安全地写入到文件
with open('data.yaml', 'w') as f:
yaml.safe_dump(data, f, default_flow_style=False)
主要区别
- 安全性:
yaml.dump() 不是安全的
,因为它可以执行 YAML 中的!!python/object
等自定义构造函数。yaml.safe_dump() 是安全的
,因为它忽略这些自定义构造函数。 - 自定义:yaml.dump() 允许使用自定义的Dumper类来自定义序列化过程,而 yaml.safe_dump() 不允许。
- 使用场景:如果你需要执行自定义的序列化逻辑,并且信任你的数据源,可以使用 yaml.dump()。否则,应该使用 yaml.safe_dump() 来避免潜在的安全风险。
安全建议
- 出于安全考虑,推荐使用 yaml.safe_dump(),除非你有特定的理由需要使用 yaml.dump() 并且完全信任你的数据源。
- 如果你使用 yaml.dump(),确保不要加载不可信的YAML数据,以避免潜在的代码执行风险。
3. 执行yaml文件中的代码
# Ultralytics YOLO 🚀, AGPL-3.0 license
# COCO 2017 dataset https://cocodataset.org by Microsoft
# Documentation: https://docs.ultralytics.com/datasets/pose/coco/
# Example usage: yolo train data=coco-pose.yaml
# parent
# ├── ultralytics
# └── datasets
# └── coco-pose ← downloads here (20.1 GB)
# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../datasets/coco-pose # dataset root dir
train: train2017.txt # train images (relative to 'path') 118287 images
val: val2017.txt # val images (relative to 'path') 5000 images
test: test-dev2017.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
# Keypoints
kpt_shape: [17, 3] # number of keypoints, number of dims (2 for x,y or 3 for x,y,visible)
flip_idx: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]
# Classes
names:
0: person
# Download script/URL (optional)
download: |
from ultralytics.utils.downloads import download
from pathlib import Path
# Download labels
dir = Path(yaml['path']) # dataset root dir
url = 'https://github.com/ultralytics/assets/releases/download/v0.0.0/'
urls = [url + 'coco2017labels-pose.zip'] # labels
download(urls, dir=dir.parent)
# Download data
urls = ['http://images.cocodataset.org/zips/train2017.zip', # 19G, 118k images
'http://images.cocodataset.org/zips/val2017.zip', # 1G, 5k images
'http://images.cocodataset.org/zips/test2017.zip'] # 7G, 41k images (optional)
download(urls, dir=dir / 'images', threads=3)
download
key 对应的val 是python 代码,可以使用exec
来执行这段代码
import yaml
with open('test.yaml', 'r') as file:
try:
data = yaml.safe_load(file)
print(data)
except yaml.YAMLError as exc:
print(exc)
exec(data['download'])
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献22条内容
所有评论(0)