【问题标题】:Loading empty dictionary when YAML file is empty (Python 3.4)当 YAML 文件为空时加载空字典(Python 3.4)
【发布时间】:2016-02-29 02:36:08
【问题描述】:

我有一个空的 YAML 文件,当我加载它时,我想将它作为一个空字典加载。例如,我有

import yaml
with open('an_empty_file.yml', 'r') as config_file:
    config=yaml.load(config_file)
    print(config) 
None

事实证明yaml.load(config_file) 将返回一个NoneType 对象,我认为这是有道理的。有没有简单的方法来返回一个空字典?

【问题讨论】:

    标签: python dictionary yaml


    【解决方案1】:

    如果它返回None,你可以只使用or,所以如果yaml.load返回None,你的配置将默认保存一个空字典:

    config = yaml.load(config_file) or {}
    

    最终,这里发生的事情,从左侧开始:

    我们现在正在为配置分配一个值。我们声明将 yaml.load(config_file) 分配给配置,但是,通过使用 or,我们在此声明中所说的是,如果它 (yaml.load) 评估为 None 或 False 条件(即在这种情况下对我们来说,无),然后我们会将{} 分配给配置。

    使用空字符串作为 config_file 的快速演示:

    >>> import yaml
    >>> config_file = ''
    >>> config = yaml.load(config_file) or {}
    >>> print(config)
    {}
    

    【讨论】:

    • 感谢您的帮助!
    • 它确实解决了问题,但我有点困惑。我熟悉 or 作为布尔运算符的用法,但我不太明白为什么它在这里工作。
    • 我很乐意解释。正在更新答案。
    • 有趣。那么NoneFalse 是否相同/相似?
    • @Vincent 。这是我们必须小心的地方。它们根本不一样,但它们评估为相同的 false 条件。如果你这样做if None == False: print('stuff')。你不会看到东西。甚至if None is False: print('asdf')。 'asdf' 不会被输出。
    【解决方案2】:

    YAML 文件的顶层可以有

    • 一个映射,由以: 分隔的键值对指示(可选择使用{} 的流式),
    • 如果是块样式,则由- 指示的序列,如果是流样式,则由[ ] 指示
    • 一个(单个)标量。

    您的文件不是映射或序列,因此它是一个标量,并且由于具有空表示的标量被认为与指定相同

    null
    

    在文件中。

    要将其加载为空字典而不是 None 你可以这样做:

    with open('an_empty_file.yml', 'r') as config_file:
        config = yaml.load(config_file)
        config = {} if config is None else config
        print(config)
    

    您应该永远不要尝试走捷径:

    config = yaml.load(config_file) or {}
    

    因为这也会导致文件带有单个标量 0:

    0
    

    单标量浮点数0.0:

    0.0
    

    使用十六进制标量 0x0:

    0x0
    

    使用空的双引号标量 ""

    ""
    

    带有一个空的单引号标量''

    ''
    

    带有一个空的折叠标量:

    >
    

    使用空的文字样式标量:

    |
    

    使用单个布尔值 False:

    False
    

    no¹:

    no
    

    off¹:

    off
    

    还有空序列:

    [
    
    ]
    

    导致config 为空字典。

    会被错误地更改为空字典的不同文件内容的数量是无穷无尽的。


    ¹这是 PyYAML 从未将 1.1 更新为 2009 年发布的 1.2 标准的结果。如果是这样,它还将转换 0o0 形式的八进制。

    【讨论】:

      猜你喜欢
      • 2016-02-04
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 2020-01-04
      • 2019-10-11
      • 2017-08-13
      • 2021-11-25
      相关资源
      最近更新 更多