Python 如何强制PyYAML将字符串作为unicode对象加载?
PyYAML包根据未标记字符串的内容将其加载为unicode或str对象 我希望在整个程序中使用unicode对象(不幸的是,现在还不能切换到Python 3) 有没有一种简单的方法可以强制PyYAML总是字符串加载unicode对象?我不想用Python 如何强制PyYAML将字符串作为unicode对象加载?,python,python-2.x,pyyaml,Python,Python 2.x,Pyyaml,PyYAML包根据未标记字符串的内容将其加载为unicode或str对象 我希望在整个程序中使用unicode对象(不幸的是,现在还不能切换到Python 3) 有没有一种简单的方法可以强制PyYAML总是字符串加载unicode对象?我不想用把我的YAML弄得乱七八糟!!python/unicode标记 # Encoding: UTF-8 import yaml menu= u"""--- - spam - eggs - bacon - crème brûlée - spam """ p
把我的YAML弄得乱七八糟!!python/unicode
标记
# Encoding: UTF-8
import yaml
menu= u"""---
- spam
- eggs
- bacon
- crème brûlée
- spam
"""
print yaml.load(menu)
输出:['spam','egs','bacon',u'cr\xe8me br\xfbl\xe9e','spam']
我想:
[u'spam',u'eggs',u'bacon',u'cr\xe8me br\xfbl\xe9e',u'spam']
这里有一个函数,你可以用PyYAML
的解码输出中的unicode
类型替换str
:
def make_str_unicode(obj):
t = type(obj)
if t in (list, tuple):
if t == tuple:
# Convert to a list if a tuple to
# allow assigning to when copying
is_tuple = True
obj = list(obj)
else:
# Otherwise just do a quick slice copy
obj = obj[:]
is_tuple = False
# Copy each item recursively
for x in xrange(len(obj)):
obj[x] = make_str_unicode(obj[x])
if is_tuple:
# Convert back into a tuple again
obj = tuple(obj)
elif t == dict:
for k in obj:
if type(k) == str:
# Make dict keys unicode
k = unicode(k)
obj[k] = make_str_unicode(obj[k])
elif t == str:
# Convert strings to unicode objects
obj = unicode(obj)
return obj
print make_str_unicode({'blah': ['the', 'quick', u'brown', 124]})
下面是一个版本,它通过总是输出
unicode
来覆盖字符串的PyYAML处理。实际上,这可能是我发布的其他响应的相同结果,除了更短的响应(即,如果使用自定义处理程序,您仍然需要确保自定义类中的字符串被转换为unicode
或自己传递unicode
字符串):
(上面给出了[u'spam',u'egs',u'bacon',u'cr\xe8me br\xfbl\xe9e',u'spam']
)
我没有在
LibYAML
(基于c的解析器)上测试它,因为我无法编译它,所以我将保留另一个答案原样。不是我想要看到的答案:(该函数可能适用于大多数常见的YAML文件,但不是所有文件。Dict键可能不是字符串,YAML允许存储自定义类型,其中可能包含字符串。如果键不是str
type,则不会将其转换为unicode
类型(如果查看代码)我同意这不是一个很好的解决方案,但它会起作用。试着make_stru unicode({0:[u'the',u'quick',u'brown',124]}
,它将不使用整数。另外,如果你进一步看代码,它只处理列表
,元组
,dicts
和str code>(其他类型/类将保持原样)如果使用自定义类型,则处理程序可能必须将str
对象转换为unicode
对象本身(或添加elif-isinstance(obj,mycustomtype:…
并单独处理)抱歉,我弄错了。谢谢你提供的解决方案。没问题,我想我可能会自己使用另一个解决方案,因为它更短/更快:-)这太完美了,谢谢!它可以在自定义类中使用字符串,也可以使用LibYAML的CLoader。而且它看起来更干净:)再次感谢!这个答案被接受已经两年多了,pyYAML仍然返回str
对象。现在是否有一种更简单的方法来强制所有unicode输出?我希望有一个更新的答案。我不这么认为,而且我认为不太可能添加它。不过,它在Python 3中工作得很好。这让YAML很烦人他是Pythonia中使用wxPython开发GUI应用程序的一半,远没有XML这样的讽刺性数据格式那么烦人,但仍然很烦人。
# -*- coding: utf-8 -*-
import yaml
from yaml import Loader, SafeLoader
def construct_yaml_str(self, node):
# Override the default string handling function
# to always return unicode objects
return self.construct_scalar(node)
Loader.add_constructor(u'tag:yaml.org,2002:str', construct_yaml_str)
SafeLoader.add_constructor(u'tag:yaml.org,2002:str', construct_yaml_str)
print yaml.load(u"""---
- spam
- eggs
- bacon
- crème brûlée
- spam
""")