如何使用ruam在python中将python/unicode标记作为unicode字符串加载

2024-05-06 09:56:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用ruamel的方式如下:

from ruamel.yaml import YAML
yaml = YAML()
print yaml.load('!!python/unicode aa')

想要的输出:

^{pr2}$

实际产量:

<ruamel.yaml.comments.TaggedScalar at 0x106557150>

我知道有一种黑客攻击可以与SafeLoader一起使用,使我产生这种行为:

SafeLoader.add_constructor('tag:yaml.org,2002:python/unicode', lambda _, node: node.value)

这将返回节点的值,这是我想要的。然而,这种黑客似乎不能与RoundTripLoader一起工作。在


Tags: fromimportnodeyaml方式unicodeloadruamel
2条回答

ipython对打印类的处理似乎有点可笑。因为它没有考虑类TaggedScalar上的__str__方法。在

RoundTripConstructor(在执行往返加载时使用)基于SafeConstructor,因此没有定义{}标记(它是为非安全的Constructor定义的)。因此,您可以返回到RoundConstructorconstruct_undefined方法,该方法创建了这个{},并将其作为正常的两步创建过程的一部分生成。在

这个TaggedScalar有一个__str__方法,在普通的CPython中,该方法返回实际的字符串值(存储在value属性中)。IPython似乎没有调用这个方法。 如果更改__str__方法的名称,那么在CPython中会得到与IPython中相同的错误结果。在

假设IPython在print-ing时确实使用了__repr__方法,那么就可以欺骗IPython了:

from ruamel.yaml import YAML
from ruamel.yaml.comments import TaggedScalar

def my_representer(x):
    try:
        if isinstance(x.value, unicode):
            return "u'{}'".format(x.value)
    except:
        pass
    return x.value

TaggedScalar.__repr__ = my_representer

yaml = YAML()

print yaml.load('!!python/unicode aa')

这给了

^{pr2}$

在我基于Linux的CPython上,当__str__方法被停用时(即__str__应该由print使用,而不是{},但IPython似乎没有这样做)。在

第一个“u”表示字符串是由“utf-8”编码的,因此如果您将“u”aa“”传递到函数中,它只会将字符串“aa”传入。所以你可以传递s“u'aa”来得到输出u'aa'。在

相关问题 更多 >