Почему yaml не может загрузить значение должным образом? - PullRequest
0 голосов
/ 04 августа 2020

Я использую следующий минимальный пример для объяснения своей проблемы:

test.py

#! /usr/bin/python3

import jinja2
import yaml
from yaml import CSafeLoader as SafeLoader

devices = [
    "usb_otg_path: 1:8",
    "usb_otg_path: m1:8",
    "usb_otg_path: 18",
]

for device in devices:
    template = jinja2.Template(device)
    device_template = template.render()
    print(device_template)
    obj = yaml.load(device_template, Loader=SafeLoader)
    print(obj)

Результат выполнения:

root@pie:~# python3 test.py
usb_otg_path: 1:8
{'usb_otg_path': 68}
usb_otg_path: m1:8
{'usb_otg_path': 'm1:8'}
usb_otg_path: 18
{'usb_otg_path': 18}

Вы могли видеть, если значение device_template равно usb_otg_path: 1:8, тогда после yaml.load 1:8 становится 68, похоже, потому что в нем есть :. Но это нормально для двух других входов.

Вы знаете, что выше это упрощенная сложная система, в которой "usb_otg_path: 1:8" - это входное значение, которое я не мог изменить, а также yaml.load - это базовый c механизм, который он использовал для изменения строки на объект python.

Затем, если возможно, я получу {'usb_otg_path': '1:8'} с некоторыми небольшими изменениями (нам нужно выполнить апстрим этого проекта, поэтому, возможно, мы не сможем сделать большие изменения, чтобы повлиять на других)? Что-то вроде изменить какие-то параметры yaml.load или что-то еще?

1 Ответ

1 голос
/ 04 августа 2020

YAML допускает форматирование числовых литералов (скаляров) как x:y:z и интерпретирует их как «шестидесятеричные», то есть с основанием 60.

1:8 таким образом интерпретируется YAML как 1*60**1 + 8*60**0, очевидно, что дает вам 68.

Примечательно, что у вас также есть m1:8 как строка и 18 как число. Похоже, вам нужны все струны? Этот ответ может быть полезен:

yaml.load(yaml, Loader=yaml.BaseLoader)

Это отключает автоматическое преобразование c значений, поскольку BaseLoader "не разрешает и не поддерживает какие-либо теги и создавать только базовые c Python объекты: списки, словари и строки Unicode. " - См. Ссылку ниже

...