当前位置: 首页 > 科技观察

大多数程序员不知道的6YAML特性

时间:2023-03-17 23:35:15 科技观察

提升您的YAML知识以编写更清晰的YAML文件YAML是一种常用于数据序列化的文件格式。有大量项目使用YAML文件进行配置,例如Docker-compose、pre-commit、TravisCI、AWSCloudformation、ESLint、Kubernetes、Ansible等。了解YAML的功能可以帮助您实现所有这些。让我们先介绍一下基础知识:YAML是JSON的超集(来源)。每个有效的JSON文件也是一个有效的YAML文件。这意味着您拥有所有预期的类型:整数、浮点数、字符串、布尔值、空值。以及序列和图表。根据您的编程语言,您可能会说“array”或“list”而不是sequence,以及“dictionary”而不是map。通常它看起来像这样:mysql:host:localhostuser:rootpassword:somethingpreprocessing_queue:#Linecommentsareavailable!-name:preprocessing.scale_and_centerwidth:32height:32-preprocessing.dot_reductionuse_anonymous:true等价符号YAML有很多等价的写法:bar,bar:baz}string_no_quotes:MontyPythonstring_double_quotes:"MontyPython"string_single_quotes:'MontyPython'bool_english:yesbool_english_no:nobool:language:no#ISO639-1codefortheNorwegianlanguage这被解释为假。您需要输入“否”或“否”。通常,我建议使用true和false之类的booleanJSON,但YAML支持11种布尔值的写法。如果您想对字符串使用引号,我也会像JSON一样使用"。您仍然需要记住“否”,但至少该文件看起来对YAML初学者来说更熟悉。如TomRitchford),还有许多更危险的情况,例如这:013映射到11,因为前导零触发八进制表示法4:30映射到270。MaxWernerKaul-Gothe和NiklasBaumstark告诉我这会自动转换为分钟(或秒?),因为它被解释为持续时间:4*60+30=270。有趣的是,这种模式在1:1:1:1:1:1:1:1:4:30个案例中仍然可能“有效”。长字符串免责声明:>Loremipsumdolorsitamet,consecteturadipiscingelit.Innecurnapellentesque,imperdieturnavitae,hendereritodio.Donecportaaliquetlaoreet.Sedviverratempusfringilla。这等同于以下JSON(为便于阅读而添加的换行符;请忽略它们):{"disclaimer":"Loremipsumdolorsitamet,consecteturadipiscingelit.Sedviverratempusfringilla."}多行字符串mail_signature:|MartinThomaTel.+491234567这等效于JSON:{"mail_signature":"MartinThomas\nTel.+491234567"}请注意,前导空格将被忽略。第一行(“MartinThomas”)确定要忽略的前导空格的数量。Anchoremail:&emailAddress"info@example.de"ID:*emailAddress这相当于下面的JSON:{"email":"info@example.de","id":"info@example.de"}&定义一个变量emailAddress,其值为“info@example.de”。然后,*表示后面是变量名。您可以对映射执行相同的操作:foo:&default_settingsdb:host:localhostname:main_dbport:1337email:admin:admin@example.comprod:*default_settingsdev:*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_settingsdb:host:localhostname:main_dbport:1337email:admin:admin@example.comprod:<<:*default_settingsapp:port:80dev:*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:!!float42id:!!str42或更复杂的转换,例如映射到未在YAML中直接指定的默认Python类型:tuple_example:!!python/tuple-1337-42set_example:!!set{1337,42}date_example:!!timestamp2020-12-31你可以这样读:importyamlimportpprintwithopen("example.yaml")asfp:data=fp.read()pp=pprint.PrettyPrinter(indent=4)passed=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有一个很好的概述:##StandardYAMLtagsYAMLPython3!!nullNone!!boolbool!!intint!!floatfloat!!binarybytes!!timestampdatetime.datetime!!omap,!!pairslistofpairs!!setset!!strstr!!seqlist!!mapdict##Python特定标签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加载它,如下所示:importyamlwithopen("example.yaml")asfp:data=fp.read()parsed=yaml.safe_load_all(data)#parsedisagenerator如果将解析后的内容转换为列表打印出来,会得到:[{'foo':'bar'},{'fizz':'buzz'}]注意这不是书写列表的替代符号。是不同的文件。静态站点生成器Pelican使用它来区分元数据和内容。我还没有看到任何其他应用程序使用此功能。编辑:ClemensTolboom提醒我静态站点生成器Jekyl也使用它。ChairatOnyaem(Par)指出oc进程也会生成这样的YAML。谢谢你的评论!下一步是什么?有许多配置文件格式,如TOML、INI、JSON、XML、dotenv,以及数据序列化格式,如Pythonspickle、HDF5、NumpysNPZ、XML。如果您有兴趣了解更多关于其中之一的信息,请告诉我!