【问题标题】:Reading multiple files in a directory with pyyaml使用pyyaml读取目录中的多个文件
【发布时间】:2019-06-15 16:20:42
【问题描述】:

我正在尝试读取目录中的所有 yaml 文件,但遇到了问题。首先,因为我使用的是 Python 2.7(并且我无法更改为 3)并且我的所有文件都是 utf-8(我还需要它们保持这种方式)。

import os
import yaml
import codecs


def yaml_reader(filepath):
    with codecs.open(filepath, "r", encoding='utf-8') as file_descriptor:
        data = yaml.load_all(file_descriptor)
        return data

def yaml_dump(filepath, data):
    with open(filepath, 'w') as file_descriptor:
        yaml.dump(data, file_descriptor)

if __name__ == "__main__":
    filepath = os.listdir(os.getcwd())
    data = yaml_reader(filepath)
    print data

当我运行这段代码时,python 给了我消息:

TypeError: coercing to Unicode: need string or buffer, list found.

我希望这个程序显示文件的内容。谁能帮帮我?

【问题讨论】:

    标签: python-2.7 pyyaml


    【解决方案1】:

    我猜问题出在文件路径上。 os.listdir(os.getcwd()) 返回目录中所有文件的列表。所以你将列表传递给 codecs.open() 而不是文件名

    【讨论】:

      【解决方案2】:

      您的代码存在多个问题,除了它是无效的 Python,在您格式化此的方式上。

      def yaml_reader(filepath):
          with codecs.open(filepath, "r", encoding='utf-8') as file_descriptor:
              data = yaml.load_all(file_descriptor)
              return data
      

      不过不需要解码,PyYAML 完全可以处理 UTF-8:

      def yaml_reader(filepath):
          with open(filepath, "rb") as file_descriptor:
              data = yaml.load_all(file_descriptor)
              return data
      

      我希望您意识到您尝试加载多个文档并始终在data 中获得一个列表,即使您的文件包含一个文档。

      然后一行:

             filepath = os.listdir(os.getcwd())
      

      给你一个文件列表,所以你需要这样做:

             filepath = os.listdir(os.getcwd())[0]
      

      或以其他方式决定要打开哪些文件。如果您想将所有文件(假设它们是 YAML)合并到一个大 YAML 文件中,您需要这样做:

      if __name__ == "__main__":
          data = []
          for filepath in os.listdir(os.getcwd()):
              data.extend(yaml_reader(filepath))
          print data
      

      您的转储程序需要更改为:

      def yaml_dump(filepath, data):
          with open(filepath, 'wb') as file_descriptor:
              yaml.dump(data, file_descriptor, allow_unicode=True, encoding='utf-8')
      

      然而,这一切都给你带来了最大的问题:你正在使用 PyYAML,它会破坏你的 YAML,删除流样式、注释、锚名称、特殊的 int/float、标量周围的引号等。除此之外,PyYAML 还有未更新以支持 YAML 1.2 文档(自 2009 年以来一直是标准)。我建议您改用 ruamel.yaml(免责声明:我是该软件包的作者),它支持 YAML 1.2 并保留 cmets 等。

      即使你一定要使用 Python 2,你也应该使用类似 Python 3 的语法,例如print 可以通过 from __future__ 导入获得。

      所以我建议你这样做:

      pip install pathlib2 ruamel.yaml
      

      然后使用:

      from __future__ import absolute_import, unicode_literals, print_function
      
      from pathlib import Path
      from ruamel.yaml import YAML
      
      if __name__ == "__main__":
          data = []
          yaml = YAML()
          yaml.preserve_quotes = True
          for filepath in Path('.').glob('*.yaml'):
              data.extend(yaml.load_all(filepath))
          print(data)
          yaml.dump(data, Path('your_output.yaml'))
      

      【讨论】:

      • 可以在google cloud的app engine环境中使用ruamel.yaml吗?
      • 我自己没有这样做,但我看不出有什么理由不这样做。如何在 app-engine 环境中安装 PyYAML?使用pip?
      • 我还没试过,但当我有答案时我会告诉你的。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      • 1970-01-01
      • 2014-07-23
      • 1970-01-01
      • 2020-12-02
      • 2021-06-12
      • 1970-01-01
      相关资源
      最近更新 更多