PyYAML 转储布尔值

PyYAML dumping boolean

我正在从 YAML 文件加载一个 yaml True/False 项目(下面的示例)。

gzip: False

这在 Jinja2 模板中被正确解释为布尔值 True。

同一个 YAML 文件正在被另一个脚本读取,作为 python CGI 表单数据传递并最终使用

写入 YAML 文件
with open(myyaml, 'w') as yaml_file:
    yaml_file.write(yaml.dump(dict, default_flow_style=False)) 

问题是这会用单引号写 True/False

gzip: 'False'

这导致 jinja2 模板不将值解释为布尔值并始终将值设置为 true

{{ if gzip }}

有没有办法转储具有被视为布尔值(我的意思是没有引号)的 True/False 值的 YAML 文件。

.dump() 只是转储它获得的数据,它必须获得一个字符串而不是布尔值作为键 gzip 的值。由于该字符串值,如果不加引号转储可能会被误解为布尔值,它会被引用。

由于您从 CGI 表单中获取 material,任何值 TrueFalse 都将是一个字符串。在转储数据之前,您必须明确地将这些从 CGI 获得的值转换为布尔值。

你可以先浏览一下你的字典,然后做一些通用的处理,然后再 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 没有被引用,因为它只能被解释为字符串。当然,上面的代码还转换了必须保留字符串的字符串 'True' 或 'False'。如果那不是你想要的,你必须select基于密钥的转换。

你的两行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))
    

    你的方式效率低下(除了表现出缺乏理解)。