В файле формата YAML как test.yaml некоторые MAC-адреса будут оцениваться как числа - PullRequest
0 голосов
/ 10 октября 2018

MAC-адрес [80: 41: 26: 53: 24: 11] был оценен как номер 62745168251, но [84: 19: 14: 15: 86: 58] был определен как строка enter image description here

enter image description here

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

Вы всегда должны использовать кавычки вокруг строковых литералов, которые начинаются с цифры и состоят из комбинации цифр и нецифровых символов, чтобы избежать путаницы из синтаксического анализатора YAML:

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

В противном случае, если ваша строкалитерал состоит из серии одно- или двузначных чисел, разделенных двоеточиями и всеми числами, но первые находятся между 0 и 59, это будет интерпретироваться как шестнадцатеричное число и будет преобразовано вэквивалентное количество секунд.Например, ваш MAC-адрес 80:41:26:53:24:11 будет рассматриваться как шестнадцатеричное число и преобразуется в:

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

, что равно 62745168251.

, так как ваш другой MAC-адрес, 84:19:14:15:86:58, имеет после первого числа число, превышающее 59 (то есть 86), оно не считается шестнадцатеричным числом и поэтому трактуется буквально как строка.

СоответствуетИсходный код можно найти в int resolver и в int конструкторе .

0 голосов
/ 10 октября 2018

Вы явно не заявляете об этом, но из-за использования yaml.load() и получения этого результата, я предполагаю, что вы используете PyYAML. Вы не должны использовать PyYAML yaml.load(), поскольку это потенциально небезопасно и совершенно не нужно .Если вам нужно придерживаться PyYAML, используйте yaml.safe_load().

В последней версии 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)

больше не поддерживается в YAML 1.2 (не явно, а спецификация YAML 1.2 указывает на независимый от языка тип 1.1, но пример был удалениз документа).

В документации YAML 1.1 явными примерами шестнадцатеричных чисел являются 190:20:30, соответственно 3:25:45 .¹целое число, за которым следует два набора (двухзначных) чисел, разделенных двумя двоеточиями (:), которые могут использоваться для указания, например, часов, минут и секунд. Однако правило (регулярное выражение) имеетнет ограничений толькоy два из этих наборов как + в конце (:[0-5]?[0-9])+ означают как минимум один раз и не имеют ограничений.В шестнадцатеричном формате между двоеточиями вы можете иметь либо однозначное число от 0-9, либо двухзначное число, где первое ограничено 0-5.

PyYAML документировано иметь синтаксический анализатор YAML 1.1 (поэтому он не был обновлен, хотя YAML 1.2 вышел в 2009 году).Он будет читать ваши MAC-адреса как шестнадцатеричные, если они соответствуют правилу, что примерно соответствует случаю, когда число между двоеточиями или после последнего двоеточия меньше 60 , как это происходит для обоих значений для ключа MAC1 и MAC2 (значения одинаковы) в значении для NETWORK2.Другие MAC-адреса имеют :86: и не являются шестнадцатеричными числами.

Если вы сбросите эти MAC-адреса из строки, используя PyYAML, они при необходимости приведут их в кавычки:

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)

, который выдает:

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

Обратите внимание, что я не сделал print(safe_dump(d)) специально, это медленнее (поскольку он должен сначала создать и заполнить внутренний буфер, извлечь и вывести содержимое),Он также добавляет дополнительный пустой символ новой строки в конце вывода.

Вы, конечно, можете указать все (или все необходимые) MAC-адреса, но более простой способ - это обновить до синтаксического анализатора YAML 1.2, например ruamel.yamlпакет (отказ от ответственности: я являюсь автором этого пакета).Что, предполагая, что ваш ввод в network.yaml, может быть сделано с помощью:

import sys
import ruamel.yaml as yaml

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

, что дает:

{'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'}}

В режиме туда-обратно, с использованием более нового 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)

для результата:

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

¹ Вы также можете иметь шестнадцатеричное значение с плавающей запятой: 20:30.15

0 голосов
/ 10 октября 2018

Не уверен, что происходит с подсветкой синтаксиса, но, может быть, есть подсказка.Имеет ли какое-то значение удаление некоторых пробелов перед MAC-адресами?

Если вы хотите, чтобы любое из ваших значений в yaml было явно оценено как строки, оберните значения в двойные или одинарные кавычки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...