pyyaml: 无标签导出

72 投票
5 回答
40606 浏览
提问于 2025-04-15 17:18

我有

>>> import yaml
>>> yaml.dump(u'abc')
"!!python/unicode 'abc'\n"

但是我想要

>>> import yaml
>>> yaml.dump(u'abc', magic='something')
'abc\n'

有什么神奇的参数可以强制不进行标记吗?

5 个回答

4

你需要一个新的“转储器”类,这个类要做标准“转储器”类所做的所有事情,但要重新定义字符串和Unicode的表示方式。

from yaml.dumper import Dumper
from yaml.representer import SafeRepresenter

class KludgeDumper(Dumper):
   pass

KludgeDumper.add_representer(str,
       SafeRepresenter.represent_str)

KludgeDumper.add_representer(unicode,
        SafeRepresenter.represent_unicode)

这就导致了

>>> print yaml.dump([u'abc',u'abc\xe7'],Dumper=KludgeDumper)
[abc, "abc\xE7"]

>>> print yaml.dump([u'abc',u'abc\xe7'],Dumper=KludgeDumper,encoding=None)
[abc, "abc\xE7"]

当然,我还是不知道怎么才能让这个看起来更好。

>>> print u'abc\xe7'
abcç

而且这会导致后面的yaml.load()出问题。

>>> yy=yaml.load(yaml.dump(['abc','abc\xe7'],Dumper=KludgeDumper,encoding=None))
>>> yy
['abc', 'abc\xe7']
>>> print yy[1]
abc�
>>> print u'abc\xe7'
abcç
19

这样怎么样:

def unicode_representer(dumper, uni):
    node = yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=uni)
    return node

yaml.add_representer(unicode, unicode_representer)

这让我在Python 2.6中,把unicode对象的输出和str对象的输出变得一样了。

In [72]: yaml.dump(u'abc')
Out[72]: 'abc\n...\n'

In [73]: yaml.dump('abc')
Out[73]: 'abc\n...\n'

In [75]: yaml.dump(['abc'])
Out[75]: '[abc]\n'

In [76]: yaml.dump([u'abc'])
Out[76]: '[abc]\n'
95

你可以用 safe_dump 来代替 dump。不过要记住,这样的话就不能表示任意的 Python 对象了。另外,当你用 load 来读取 YAML 文件时,你会得到一个 str 对象,而不是 unicode 对象。

撰写回答