大多数程序员都不知道的6个YAML功能

提升您的YAML知识以编写更清晰的YAML文件

YAML是一种常用于数据序列化的文件格式。有大量使用YAML文件进行配置的项目,例如Docker-compose,pre-commit,TravisCI,AWS Cloudformation,ESLint,Kubernetes,Ansible等。了解YAML的功能可以帮助您实现所有这些功能。

让我们先介绍一下基础知识:YAML是JSON(源)的超集。每个有效的JSON文件也是一个有效的YAML文件。这意味着您拥有所有期望的类型:整数,浮点数,字符串,布尔值,空值。以及序列和图。根据您的编程语言,您可能说“ array”或“ list”而不是序列,而说“ dictionary”而不是map。

通常看起来像这样:

 
 
 
 
  1. mysql:
  2.   host: localhost
  3.   user: root
  4.   password: something
  5. preprocessing_queue:  # Line comments are available!
  6.   - name: preprocessing.scale_and_center
  7.     width: 32
  8.     height: 32
  9.   - preprocessing.dot_reduction
  10. use_anonymous: true

等效符号

YAML有很多等效的编写方法:

 
 
 
 
  1. list_by_dash:
  2.   - foo
  3.   - bar
  4. list_by_square_bracets: [foo, bar]
  5. map_by_indentation:
  6.   foo: bar
  7.   bar: baz
  8. map_by_curly_braces: {foo: bar, bar: baz}
  9. string_no_quotes: Monty Python
  10. string_double_quotes: "Monty Python"
  11. string_single_quotes: 'Monty Python'
  12. bool_english: yes
  13. bool_english_no: no
  14. bool_python: True
  15. bool_json: true

这里有些警告:

 
 
 
 
  1. language: no # ISO 639-1 code for the Norwegian language

此否被解释为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的情况下“工作”。

长字符串

 
 
 
 
  1. disclaimer: >
  2.     Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  3.     In nec urna pellentesque, imperdiet urna vitae, hendrerit
  4.     odio. Donec porta aliquet laoreet. Sed viverra tempus fringilla.

这等效于以下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."}

多行字符串

 
 
 
 
  1. mail_signature: |
  2.       Martin Thoma
  3.       Tel. +49 123 4567

这等效于JSON:

{"mail_signature": "Martin Thoma\nTel. +49 123 4567"}

请注意如何忽略前导空格。第一行(“ Martin Thoma”)确定忽略的前导空白的数量。

 
 
 
 
  1. email: &emailAddress "info@example.de"
  2. id: *emailAddress

这等效于以下JSON:

{"email": "info@example.de", "id": "info@example.de"}

&定义了一个变量emailAddress,其值为“ info@example.de。然后,*表示紧随其后的是变量名。

您可以对映射执行相同的操作:

 
 
 
 
  1. foo: &default_settings
  2.   db:
  3.     host: localhost
  4.     name: main_db
  5.     port: 1337
  6.   email:
  7.     admin: admin@cdxwcx.com
  8. prod: *default_settings
  9. dev: *default_settings

这使:

 
 
 
 
  1. { "dev": { "db": {"host":
  2.                   "localhost",
  3.                   "name": "main_db",
  4.                   "port": 1337},
  5.            "email": {"admin": "admin@cdxwcx.com"}},
  6.   "foo": { "db": {"host": "localhost",
  7.                   "name": "main_db",
  8.                   "port": 1337},
  9.            "email": {"admin": "admin@cdxwcx.com"}},
  10.   "prod": { "db": {"host": "localhost",
  11.                    "name": "main_db",
  12.                    "port": 1337},
  13.             "email": {"admin": "admin@cdxwcx.com"}}}

现在,您可能想在开发和生产设置中插入密码。您可以使用合并键<<来做到这一点:

 
 
 
 
  1. foo: &default_settings
  2.   db:
  3.     host: localhost
  4.     name: main_db
  5.     port: 1337
  6.   email:
  7.     admin: admin@cdxwcx.com
  8. prod:
  9.   <<: *default_settings
  10.   app:
  11.     port: 80
  12. dev: *default_settings

等效于以下JSON:

 
 
 
 
  1. { "foo": { "db": {"host": "localhost",
  2.                   "name": "main_db",
  3.                   "port": 1337},
  4.            "email": {"admin": "admin@cdxwcx.com"}},
  5.   "prod": { "app": {"port": 80},
  6.             "db": {"host": "localhost",
  7.                    "name": "main_db",
  8.                    "port": 1337},
  9.             "email": {"admin": "admin@cdxwcx.com"}},
  10.   "dev": { "db": {"host": "localhost",
  11.                   "name": "main_db",
  12.                   "port": 1337},
  13.            "email": {"admin": "admin@cdxwcx.com"}},}

类型转化

双重爆炸!在YAML中有特殊含义。它被称为“第二标签句柄”和!tag:yaml.org,2002 :(源)的简写。

您可以像这样进行简单的转换:

 
 
 
 
  1. price: !!float 42
  2. id: !!str 42

或更复杂的内容,例如映射到直接在YAML中未指定的默认Python类型:

 
 
 
 
  1. tuple_example: !!python/tuple
  2.   - 1337
  3.   - 42
  4. set_example: !!set {1337, 42}
  5. date_example: !!timestamp 2020-12-31

您可以这样阅读:

 
 
 
 
  1. import yaml
  2. import pprint
  3. with open("example.yaml") as fp:
  4.     data = fp.read()
  5. pp = pprint.PrettyPrinter(indent=4)
  6. pased = yaml.unsafe_load(data)
  7. pp.pprint(pased)

你会得到这个:

 
 
 
 
  1. {   'date_example': datetime.date(2020, 12, 31),
  2.     'set_example': {1337, 42},
  3.     'tuple_example': (1337, 42)}

本示例使用特定于Python的标记!! python / tuple和一些标准的YAML标记。PyYaml有一个不错的概述:

 
 
 
 
  1. ## Standard YAML tags
  2. YAML               Python 3
  3. !!null             None
  4. !!bool             bool
  5. !!int              int
  6. !!float            float
  7. !!binary           bytes
  8. !!timestamp        datetime.datetime
  9. !!omap, !!pairs    list of pairs
  10. !!set              set
  11. !!str              str
  12. !!seq              list
  13. !!map              dict
  14. ## Python-specific tags
  15. YAML               Python 3
  16. !!python/none      None
  17. !!python/bool      bool
  18. !!python/bytes     bytes
  19. !!python/str       str
  20. !!python/unicode   str
  21. !!python/int       int
  22. !!python/long      int
  23. !!python/float     float
  24. !!python/complex   complex
  25. !!python/list      list
  26. !!python/tuple     tuple
  27. !!python/dict      dict
  28. ## Complex Python tags
  29. !!python/name:module.name         module.name
  30. !!python/module:package.module    package.module
  31. !!python/object:module.cls        module.cls instance
  32. !!python/object/new:module.cls    module.cls instance
  33. !!python/object/apply:module.f    value of f(...)

请注意,加载非标准标签是不安全的!可以使用!! python / object / apply:module.f执行任意代码。在PyYaml中,您需要yaml.unsafe_load才能使用它。因此,您可能不应该使用它!

一个YAML中的多个文档

YAML中的三个破折号分别表示文档:

 
 
 
 
  1. foo: bar
  2. ---
  3. fizz: buzz

在Python中,您可以使用PyYAML像这样加载它:

 
 
 
 
  1. import yaml
  2. with open("example.yaml") as fp:
  3.     data = fp.read()
  4. parsed = yaml.safe_load_all(data)  # parsed is a generator

如果将已分析的内容转换为列表并打印出来,则会得到:

 
 
 
 
  1. [{'foo': 'bar'}, {'fizz': 'buzz'}]

请注意,这不是写列表的替代符号。是不同的文件。

静态站点生成器Pelican使用它来区分元数据和内容。我还没有看到其他任何使用此功能的应用程序。编辑:Clemens Tolboom提醒我,静态网站生成器Jekyl也使用它。Chairat Onyaem(Par)指出oc进程也会生成此类YAML。谢谢你的评论!

下一步是什么?

有很多配置文件格式,例如TOML,INI,JSON,XML,dotenv,以及数据序列化格式,例如Pythons pickle,HDF5,Numpys NPZ,XML。如果您有兴趣了解其中一个的更多信息,请告诉我!

本文标题:大多数程序员都不知道的6个YAML功能
URL地址:http://www.shufengxianlan.com/qtweb/news11/324261.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联