使用pyyaml读取目录中的多个文件
Reading multiple files in a directory with pyyaml
我正在尝试读取目录中的所有 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.
我想让这个程序显示文件的内容。谁能帮帮我?
我想问题出在文件路径上。
os.listdir(os.getcwd()) returns 目录中所有文件的列表。所以您将列表传递给 codecs.open() 而不是文件名
你的代码有多个问题,除了它是无效的 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,删除 flow-style、注释、锚点名称、特殊 int/float、标量周围的引号等. 除此之外,PyYAML 尚未更新以支持 YAML 1.2 文档(自 2009 年以来一直是标准)。我建议您改用 ruamel.yaml
(免责声明:我是该软件包的作者),它支持 YAML 1.2 并保留注释等。
即使您必须使用 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'))
我正在尝试读取目录中的所有 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.
我想让这个程序显示文件的内容。谁能帮帮我?
我想问题出在文件路径上。 os.listdir(os.getcwd()) returns 目录中所有文件的列表。所以您将列表传递给 codecs.open() 而不是文件名
你的代码有多个问题,除了它是无效的 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,删除 flow-style、注释、锚点名称、特殊 int/float、标量周围的引号等. 除此之外,PyYAML 尚未更新以支持 YAML 1.2 文档(自 2009 年以来一直是标准)。我建议您改用 ruamel.yaml
(免责声明:我是该软件包的作者),它支持 YAML 1.2 并保留注释等。
即使您必须使用 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'))