提升您的YAML知识以编写更清晰的YAML文件
YAML是一种常用于数据序列化的文件格式。有大量使用YAML文件进行配置的项目,例如Docker-compose,pre-commit,TravisCI,AWS Cloudformation,ESLint,Kubernetes,Ansible等。了解YAML的功能可以帮助您实现所有这些功能。
让我们先介绍一下基础知识:YAML是JSON(源)的超集。每个有效的JSON文件也是一个有效的YAML文件。这意味着您拥有所有期望的类型:整数,浮点数,字符串,布尔值,空值。以及序列和图。根据您的编程语言,您可能说“ array”或“ list”而不是序列,而说“ dictionary”而不是map。
通常看起来像这样:
- mysql:
- host:localhost
- user:root
- password:something
- preprocessing_queue:#Linecommentsareavailable!
- –name:preprocessing.scale_and_center
- width:32
- height:32
- -preprocessing.dot_reduction
- use_anonymous:true
等效符号
YAML有很多等效的编写方法:
- list_by_dash:
- -foo
- -bar
- list_by_square_bracets:[foo,bar]
- map_by_indentation:
- foo:bar
- bar:baz
- map_by_curly_braces:{foo:bar,bar:baz}
- string_no_quotes:MontyPython
- string_double_quotes:"MontyPython"
- string_single_quotes:'MontyPython'
- bool_english:yes
- bool_english_no:no
- bool_python:True
- bool_json:true
这里有些警告:
- language:no#ISO639-1codefortheNorwegianlanguage
此否被解释为false。您需要输入“ no”或“ no”。
通常,我建议像布尔值JSON一样使用true和false,但是YAML支持11种写布尔值的方法。如果您想对字符串使用引号,我也将像JSON一样使用“。您仍然需要记住” no“,但是至少该文件看起来对YAML初学者更熟悉。
正如汤姆·里奇福德(Tom Ritchford)所指出的,还有更多类似的危险案例:
- 013映射到11,因为前导零触发八进制表示法
- 4:30映射到270。Max Werner Kaul-Gothe和Niklas Baumstark告诉我,这被自动转换为分钟(或秒?),因为它被解释为持续时间:4 * 60 + 30 = 270。有趣的是,这种模式仍然可以在1:1:1:1:1:1:1:1:4:30的情况下“工作”。
长字符串
- disclaimer:>
- Loremipsumdolorsitamet,consecteturadipiscingelit.
- Innecurnapellentesque,imperdieturnavitae,hendrerit
- odio.Donecportaaliquetlaoreet.Sedviverratempusfringilla.
这等效于以下JSON(为便于阅读,添加了换行符;请忽略它们):
{"disclaimer": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In nec urna pellentesque, imperdiet urna vitae, hendrerit odio. Donec porta aliquet laoreet. Sed viverra tempus fringilla."}
多行字符串
- mail_signature:|
- MartinThoma
- Tel.+491234567
这等效于JSON:
{"mail_signature": "Martin Thoma\\nTel. +49 123 4567"}
请注意如何忽略前导空格。第一行(“ Martin Thoma”)确定忽略的前导空白的数量。
锚
- email:&emailAddress"info@example.de"
- id:*emailAddress
这等效于以下JSON:
{"email": "info@example.de", "id": "info@example.de"}
&定义了一个变量emailAddress,其值为“ info@example.de。然后,*表示紧随其后的是变量名。
您可以对映射执行相同的操作:
- foo:&default_settings
- db:
- host:localhost
- name:main_db
- port:1337
- email:
- admin:admin@example.com
- prod:*default_settings
- dev:*default_settings
这使:
- {"dev":{"db":{"host":
- "localhost",
- "name":"main_db",
- "port":1337},
- "email":{"admin":"admin@example.com"}},
- "foo":{"db":{"host":"localhost",
- "name":"main_db",
- "port":1337},
- "email":{"admin":"admin@example.com"}},
- "prod":{"db":{"host":"localhost",
- "name":"main_db",
- "port":1337},
- "email":{"admin":"admin@example.com"}}}
现在,您可能想在开发和生产设置中插入密码。您可以使用合并键<<来做到这一点:
- foo:&default_settings
- db:
- host:localhost
- name:main_db
- port:1337
- email:
- admin:admin@example.com
- prod:
- <<:*default_settings
- app:
- port:80
- dev:*default_settings
等效于以下JSON:
- {"foo":{"db":{"host":"localhost",
- "name":"main_db",
- "port":1337},
- "email":{"admin":"admin@example.com"}},
- "prod":{"app":{"port":80},
- "db":{"host":"localhost",
- "name":"main_db",
- "port":1337},
- "email":{"admin":"admin@example.com"}},
- "dev":{"db":{"host":"localhost",
- "name":"main_db",
- "port":1337},
- "email":{"admin":"admin@example.com"}},}
类型转化
双重爆炸!在YAML中有特殊含义。它被称为“第二标签句柄”和!tag:yaml.org,2002 :(源)的简写。
您可以像这样进行简单的转换:
- price:!!float42
- id:!!str42
或更复杂的内容,例如映射到直接在YAML中未指定的默认Python类型:
- tuple_example:!!python/tuple
- -1337
- -42
- set_example:!!set{1337,42}
- date_example:!!timestamp2020-12-31
您可以这样阅读:
- importyaml
- importpprint
- withopen("example.yaml")asfp:
- data=fp.read()
- pp=pprint.PrettyPrinter(indent=4)
- pased=yaml.unsafe_load(data)
- pp.pprint(pased)
你会得到这个:
- {'date_example':datetime.date(2020,12,31),
- 'set_example':{1337,42},
- 'tuple_example':(1337,42)}
本示例使用特定于Python的标记!! python / tuple和一些标准的YAML标记。PyYaml有一个不错的概述:
- ##StandardYAMLtags
- YAMLPython3
- !!nullNone
- !!boolbool
- !!intint
- !!floatfloat
- !!binarybytes
- !!timestampdatetime.datetime
- !!omap,!!pairslistofpairs
- !!setset
- !!strstr
- !!seqlist
- !!mapdict
- ##Python-specifictags
- YAMLPython3
- !!python/noneNone
- !!python/boolbool
- !!python/bytesbytes
- !!python/strstr
- !!python/unicodestr
- !!python/intint
- !!python/longint
- !!python/floatfloat
- !!python/complexcomplex
- !!python/listlist
- !!python/tupletuple
- !!python/dictdict
- ##ComplexPythontags
- !!python/name:module.namemodule.name
- !!python/module:package.modulepackage.module
- !!python/object:module.clsmodule.clsinstance
- !!python/object/new:module.clsmodule.clsinstance
- !!python/object/apply:module.fvalueoff(…)
请注意,加载非标准标签是不安全的!可以使用!! python / object / apply:module.f执行任意代码。在PyYaml中,您需要yaml.unsafe_load才能使用它。因此,您可能不应该使用它!
一个YAML中的多个文档
YAML中的三个破折号分别表示文档:
- foo:bar
- —
- fizz:buzz
在Python中,您可以使用PyYAML像这样加载它:
- importyaml
- withopen("example.yaml")asfp:
- data=fp.read()
- parsed=yaml.safe_load_all(data)#parsedisagenerator
如果将已分析的内容转换为列表并打印出来,则会得到:
- [{'foo':'bar'},{'fizz':'buzz'}]
请注意,这不是写列表的替代符号。是不同的文件。
静态站点生成器Pelican使用它来区分元数据和内容。我还没有看到其他任何使用此功能的应用程序。编辑:Clemens Tolboom提醒我,静态网站生成器Jekyl也使用它。Chairat Onyaem(Par)指出oc进程也会生成此类YAML。谢谢你的评论!
下一步是什么?
有很多配置文件格式,例如TOML,INI,JSON,XML,dotenv,以及数据序列化格式,例如Pythons pickle,HDF5,Numpys NPZ,XML。如果您有兴趣了解其中一个的更多信息,请告诉我!
原文地址:https://www.toutiao.com/i6934590069487518212/