2016-11-03 4 views
1

Я загружаю yaml True/False элемент (пример ниже) из файла YAML.PyYAML dumping boolean

gzip: False 

Это правильно интерпретируется в шаблоне Jinja2 как boolean True.

тот же файл YAML считывается другой сценарий, перешел в качестве формы питон CGI данных и в конечном итоге записывается в файл YAML, используя

with open(myyaml, 'w') as yaml_file: 
    yaml_file.write(yaml.dump(dict, default_flow_style=False)) 

Вопрос заключается в том, что это то пишет True/False с одиночная кавычка

gzip: 'False' 

, который вызывает шаблон jinja2 не интерпретировать значение как логическое значение и всегда задает значение, как истинное в

{{ if gzip }} 

Есть ли способ сбрасывать файл YAML с значениями True/False, которые обрабатываются как логические (я имею в виду без кавычек).

+0

Конечно, он не будет автоматически анализировать строку '' False'' как boolean.Это не особенно важно ни для Jinja2, ни для YAML. Это то же самое везде. Как он должен знать, что вы хотите проанализировать значение? Вам нужно будет сделать это явно, если ваши данные не будут правильно сохранены в файле YAML. – poke

+0

Проблема в том, что цитаты добавляются пользователем yaml.dump. Первоначально, когда я создаю yaml, он не имеет кавычек, или вопрос может быть перефразирован как Как я могу сбросить значение в yaml, явно указывая его как boolean, а не string. Я думаю, что form.get преобразует True/False в строку. –

+0

'yaml.dump' will * not * dump boolean как строка, если он был фактическим булевым раньше:' yaml.dump ({'Foo': 'Bar', 'Baz': True}) 'дает вам' {Baz: true, Foo: Bar} \ n'' - Нет кавычек. В любом случае, YAML должен быть в основном quoteless. – poke

ответ

1

.dump() просто сбрасывает данные, которые он получает, и он должен был получить строку вместо логического значения в качестве значения для ключа gzip. Так как это строковое значение, если выбрано без кавычек, может быть неверно истолковано как логическое, оно будет процитировано.

Поскольку вы получаете свой материал из формы CGI, любое значение True или False будет строкой. Перед сбросом данных вам явно необходимо преобразовать эти значения из CGI в booleans.

Вы можете пройти через свой словарь и сделать что-то родовое обработки перед вами dump:

import sys 
import yaml 

# simulating getting string type values from CGI 
data = dict(gzip='False', intval="1", strval="abc") 

for k in data: 
    v = data[k] 
    try: 
     v = int(v) 
     data[k] = v 
    except ValueError: 
     vl = v.lower() 
     if vl == 'false': 
      data[k] = False 
     elif vl == 'true': 
      data[k] = True 

yaml.safe_dump(data, sys.stdout, default_flow_style=False) 

дает:

gzip: false 
intval: 1 
strval: abc 

Пожалуйста, обратите внимание, что abc не котируется, потому что не может быть истолковано как угодно else, но строка. Вышеупомянутое, конечно, также преобразует строки «True» или «False», которые должны были бы оставаться строками. Если это не то, что вы хотите, вам нужно выбрать преобразование на основе ключа.

Есть две другие основные проблемы, связанные с вашими двумя линиями Python:

with open(myyaml, 'w') as yaml_file: 
    yaml_file.write(yaml.dump(dict, default_flow_style=False)) 
  1. Вы никогда не должны использовать Python ключевое слово (dict) в качестве имени переменной, просто напрашиваются на неприятности позже в ваш код.
  2. yaml.dump() сбрасывает данные в поток. У него есть средство, которое, если вы не укажете поток, куда нужно перейти, вывод записывается во внутренний объект потока, из которого возвращается окончательное значение. Вы не должны злоупотреблять этим, чтобы затем записать это возвращаемое значение в yaml_file. Вместо этого:

    with open(myyaml, 'w') as yaml_file: 
        yaml.dump(dict, yaml_file, default_flow_style=False)) 
    

    Ваш способ неэффективен (кроме проявления непонимания).

+0

Ключевое слово dict не использовалось. Я просто хочу быстро сказать, что в коде использовался словарь. Спасибо, что указали на проблему с моим стилем yaml.dump. Я отвечу на ваш ответ, поскольку форма действительно получает строковое значение вместо boolean. –

+0

@AnoopPAlias ​​Извините за неправильное толкование 'dict'. В таких случаях я могу порекомендовать использовать что-то вроде 'my_dict'. Вы всегда будете видеть, что следующий посетитель здесь вырезает и вставляет ваш код, и он будет работать до тех пор, пока ключевое слово не будет использовано для его реальной цели (конечно, кем-то другим, поддерживающим код несколько лет вперед) :-). – Anthon