简体   繁体   English

在YAML格式的文件test.yaml中,某些MAC地址将被判断为数字

[英]In the YAML format file as test.yaml, some MAC addresses will be judged as number

the MAC address of [80:41:26:53:24:11] has been judged as number 62745168251 but [84:19:14:15:86:58] has been judged as string MAC地址[80:41:26:53:24:11]已被判断为数字62745168251,但[84:19:14:15:86:58]已被判断为字符串 在此处输入图片说明

在此处输入图片说明

You should always use quotes around string literals that start with a digit and consist of a mix of digits and non-digit characters to avoid confusion from the YAML parser: 您应该始终在以数字开头并且包含数字和非数字字符的字符串文字周围使用引号,以避免YAML解析器造成混淆:

MAC1: "80:41:26:53:24:11"

Otherwise, if your string literal consists of a series of one or two-digit numbers delimited by colons and all numbers but the first are between 0 and 59 , it would be interpreted as a sexagesimal number and would be converted to the equivalent number of seconds. 否则,如果您的字符串文字包含一系列以冒号分隔的一位数或两位数,而除第一个以外的所有数字都在059之间,则它将被解释为十六进制数,并将转换为等效的秒数。 For example, your MAC-address 80:41:26:53:24:11 would be treated as a sexagesimal number and converted to: 例如,您的MAC地址80:41:26:53:24:11将被视为十六进制数字,并转换为:

(((((80*60)+41)*60+26)*60+53)*60+24)*60+11

which is equal to 62745168251 . 等于62745168251

Since your other MAC-address, 84:19:14:15:86:58 , has a number after the first number that is over 59 ( 86 that is), it is not considered as a sexagesimal number and is therefore treated literally as a string. 由于您的其他MAC地址84:19:14:15:86:58在第一个数字之后有一个大于59 (即86 ),因此它不被视为十六进制数字,因此按字面意义对待一个字符串。

Relevant source code can be found in the int resolver and the int constructor . 相关源代码可以在int解析器int构造函数中找到

You don't explicitly state it, but from the use of yaml.load() and getting that result, my guess is that you are using PyYAML. 您没有明确声明它,但是从使用yaml.load()并获得该结果来看,我的猜测是您正在使用PyYAML。 You should not be using PyYAML yaml.load() as this is potentially unsafe and completely unnecessary . 您不应该使用PyYAML yaml.load()因为这可能是不安全的,而且完全没有必要 If you need to stick with PyYAML, use yaml.safe_load() instead. 如果您需要坚持使用PyYAML,请改用yaml.safe_load()

In the latest version of YAML]( (1.2 released in 2009) the core schema of what counts as an int has changed from the previous version (1.1 from 2005). The most notable differences are that 077 is no longer an octal in YAML 1.2 (use 0o77 ) and that sexagesimals , in the YAML 1.1 documentation indicated by this validation rule: 在YAML]((1.2的最新版本于2009年发布)的核心架构是什么算作一个int已经发生变化 ,从以前的版本(1.1 2005)。最显着的区别是077不再在YAML 1.2八进制(使用0o77 ),并且sexagesimals ,通过这个验证规则所指示的YAML 1.1文档中:

|[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+ # (base 60)

are no longer supported in YAML 1.2 (not explicitly, and the YAML 1.2 specification points to the 1.1 language independent type, but the example has been removed from the document). 在YAML 1.2中不再受支持(没有明确规定,并且YAML 1.2规范指向与1.1语言无关的类型,但是该示例已从文档中删除)。

In the YAML 1.1 documentation the explicit examples for sexagesimal ints are 190:20:30 , resp. 在YAML 1.1文档六十进制整数显式实例 190:20:30RESP。 3:25:45 .¹ This seems to be an integer followed by two sets of (two digit) number and all seperated by two colons ( : ), that can be used to indicate eg hours, minutes and seconds. 3:25:45 .¹这似乎是一个整数,其后两组 (两位数字)数目和所有通过两个冒号分隔( : ),可以被用来指示例如小时,分钟和秒。 The rule (regex) however has no limit on only two of these sets as the + at the end of (:[0-5]?[0-9])+ means at least one time and has no restriction. 规则(正则表达式),但是对这些仅套作为两个没有限制+在的结尾(:[0-5]?[0-9])+是指至少一个的时间和不存在任何限制。 In a sexagesimal, between the colons, you can either have a one digit number from 0-9 or a two digit number where the first is restricted to 0-5 . 以十六进制形式,在冒号之间,您可以使用0-9的一位数字,也可以使用两位数字,其中第一个数字限制为0-5

PyYAML is documented to feature a YAML 1.1 parser (so it has not been updated although YAML 1.2 came out in 2009). PyYAML已记录为具有YAML 1.1解析器(因此,尽管2009年推出了YAML 1.2,但尚未更新)。 It will read your MAC addresses as sexagesimal, if they match the rule, which roughly said happens when the number between the colons or after the last colon is less than 60 , as happens for both the values for key MAC1 and MAC2 (the values are the same) in the value for NETWORK2 . 如果它们符合规则,它将读取您的MAC地址为十六进制,这粗略地说发生在冒号之间或最后一个冒号之后的数字小于60时,这对于密钥MAC1MAC2的值(相同)在NETWORK2的值中。 The other MAC addresses have :86: in them and are not sexagesimals. 其他MAC地址中包含:86: :,不是十六进制。

If you would dump these MAC addresses from a string using PyYAML, it will quote them for you when necessary: 如果您要使用PyYAML从字符串中转储这些MAC地址,则它将在必要时为您引用它们:

import sys
import yaml

d = dict(mac1='84:19:14:15:86:58', mac2='80:41:26:53:24:11')
yaml.safe_dump(d, sys.stdout)

which dumps: 哪个转储:

{mac1: '84:19:14:15:86:58', mac2: '80:41:26:53:24:11'}

Please note that I did not do print(safe_dump(d)) on purpose, it is slower (as it has to first create and fill an internal buffer, retrieve and stream out the contents). 请注意,我不是print(safe_dump(d))进行print(safe_dump(d)) ,它比较慢(因为它必须先创建并填充内部缓冲区,然后检索并输出内容)。 It also adds an extra empty newline at the end of the output. 它还在输出末尾添加了一个额外的空换行符。

You can of course quote all (or all necessary) MAC addresses, but the easier way is upgrade to a YAML 1.2 parser like the ruamel.yaml package (disclaimer: I am the author of that package). 您当然可以引用所有(或所有必要的)MAC地址,但是更简单的方法是升级到ruamel.yaml包之类的YAML 1.2解析器(免责声明:我是该包的作者)。 Which, assuming your input is in network.yaml , can be done using: 假设您的输入在network.yaml ,可以使用:

import sys
import ruamel.yaml as yaml

with open('network.yaml') as fp:
    data = yaml.safe_load(fp)
print(data)

which gives: 这使:

{'NETWORK1': {'BOND_MODE': 4, 'BOND_NAME': 'bond0', 'MAC1': '84:19:14:15:86:58', 'MAC2': '84:19:14:15:86:59'}, 'NETWORK2': {'BOND_MODE': 1, 'BOND_NAME': 'bond0', 'BLAN_ID': 820, 'MAC1': '80:41:26:53:24:11', 'MAC2': '80:41:26:53:24:11'}}

In round-trip mode, using the newer API, ruamel.yaml will not insert quotes when dumping, as they are unnecessary for YAML 1.2: 在往返模式下,使用较新的API,ruamel.yaml不会在转储时插入引号,因为YAML 1.2不需要引号:

import sys
import ruamel.yaml
from pathlib import Path

network_file = Path('network.yaml')

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(network_file)
yaml.dump(data, sys.stdout)

for result: 结果:

NETWORK1:
  BOND_MODE: 4
  BOND_NAME: bond0
  MAC1: 84:19:14:15:86:58
  MAC2: 84:19:14:15:86:59

NETWORK2:
  BOND_MODE: 1
  BOND_NAME: bond0
  BLAN_ID: 820
  MAC1: 80:41:26:53:24:11
  MAC2: 80:41:26:53:24:11

¹ You can also have a sexagesimal float: 20:30.15 ¹ 您也可以使用六进制浮点数: 20:30.15

Not sure what's going on with your syntax highlighting, but, maybe there's a clue there. 不知道语法突出显示是怎么回事,但是,也许有一个线索。 Does removing some of the whitepaces before the MAC addresses make any difference? 在MAC地址生效之前删除一些空白是否会有所不同?

If you want any of your values in yaml to be explicitly evaluated as strings, wrap the values in double or single quotes. 如果您希望将yaml中的任何值显式评估为字符串,请将这些值用双引号或单引号引起来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM