首页 > 解决方案 > 使用 Python 读取 YAML 文件会导致 yaml.scanner.ScannerError: mapping values are not allowed here

问题描述

我正在使用以下代码:

import yaml
with open('/Users/edamame/my_logins/my_config.yaml', 'r') as infile:
    db_cfg = yaml.safe_load(infile)

它试图阅读my_config.yaml

database_info:
    username: edamame
    password: mypassword
    host: 1.2.3.4
    port: 3306
    database: mydb

但出现以下错误:

Traceback (most recent call last):
  File "/Users/edamame/my_project/extract_appointments.py", line 16, in <module>
    db_cfg = yaml.safe_load(infile)
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/__init__.py", line 94, in safe_load
    return load(stream, SafeLoader)
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/__init__.py", line 72, in load
    return loader.get_single_data()
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/constructor.py", line 35, in get_single_data
    node = self.get_single_node()
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/composer.py", line 36, in get_single_node
    document = self.compose_document()
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/composer.py", line 55, in compose_document
    node = self.compose_node(None, None)
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/composer.py", line 127, in compose_mapping_node
    while not self.check_event(MappingEndEvent):
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/parser.py", line 98, in check_event
    self.current_event = self.state()
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/parser.py", line 428, in parse_block_mapping_key
    if self.check_token(KeyToken):
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/scanner.py", line 116, in check_token
    self.fetch_more_tokens()
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/scanner.py", line 220, in fetch_more_tokens
    return self.fetch_value()
  File "/Users/edamame/my_project/venv/lib/python3.6/site-packages/yaml/scanner.py", line 576, in fetch_value
    self.get_mark())
yaml.scanner.ScannerError: mapping values are not allowed here
  in "/Users/edamame/my_logins/my_config.yaml", line 5, column 9

这是我的装置: 在此处输入图像描述 知道我在这里错过了什么吗?

标签: pythonyamlpyyaml

解决方案


您显示的输入不会产生该错误。你可以在这里试试:

您很可能有一些空白差异,很可能port: 3306在行中。请注意,由于 PyYAML 早于最新的 YAML 标准(2009 年的 1.2)它仍然考虑一些 Unicode 空白字符空白,尽管标准没有。

如果您无法通过查看文件找到导致此问题的原因,则有两种可能的选择:

  • 尝试一次将文件复制并粘贴到在线解析器中,直到看到弹出错误。这可以让您清楚地指示哪条线路是错误的。
  • 使用 YAML 转储器从 Python 构建的数据中转储所需的数据结构

后者在 PyYAML 中不容易完成,因为它将在写入时对映射的键进行排序。

import sys
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap as cm

data = cm()
data['database_info'] = d = cm()
d['username'] = 'edamame'
d['password'] = 'mypassword'
d['host'] = '1.2.3.4'
d['port'] = 3306
d['database'] = 'mydb'


yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)

with open('my_config.yaml', 'w') as ofp:
    yaml.dump(data, ofp)

生成以下内容my_config.yaml

database_info:
    username: edamame
    password: mypassword
    host: 1.2.3.4
    port: 3306
    database: mydb

一个(甚至)PyYAML 应该能够读取的文件。


推荐阅读