web-dev-qa-db-fra.com

pyyaml: dumping sans étiquettes

J'ai

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

Mais je veux

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

Quel param magique ne force pas le marquage?

64
Paul Tarjan

Vous pouvez utiliser safe_dump au lieu de dump. Gardez simplement à l’esprit qu’il ne pourra alors pas représenter d’objets Python arbitraires. De plus, lorsque vous load le YAML, vous obtiendrez un objet str au lieu de unicode.

82
interjay

Que dis-tu de ça:

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)

Cela semble faire que le vidage des objets unicode fonctionne de la même manière que le vidage des objets str pour moi (Python 2.6).

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'
18
Michał Marczyk

Vous avez besoin d'une nouvelle classe dumper qui exécute tout ce que fait la classe standard Dumper, mais remplace les représentants pour str et 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)

Qui conduit à

>>> 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"]

Certes, je suis toujours perplexe sur la façon de garder cette jolie.

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

Et cela casse plus tard 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ç
4
Chris Dukes

petit ajout à l'excellente réponse d'interjay, vous pouvez garder votre unicode sur une recharge si vous vous occupez de l'encodage de vos fichiers.

# -*- coding: utf-8 -*-
import yaml
import codecs

data = dict(key = u"abcç\U0001F511")

fn = "test2.yaml"
with codecs.open(fn, "w", encoding="utf-8") as fo:
    yaml.safe_dump(data, fo)

with codecs.open(fn, encoding="utf-8") as fi:
    data2 = yaml.safe_load(fi)

print ("data2:", data2, "type(data.key):", type(data2.get("key")) )

print data2.get("key")

test2.yaml contenus dans mon éditeur:

{key: "abc\xE7\uD83D\uDD11"}

sorties d'impression:

('data2:', {'key': u'abc\xe7\U0001f511'}, 'type(data.key):', <type 'unicode'>) abcç????

De plus, après avoir lu http://nedbatchelder.com/blog/201302/war_is_peace.html je suis à peu près sûr que safe_load/safe_dump est où je veux être de toute façon.

2
JL Peyret

Je viens de commencer avec Python et YAML, mais cela peut probablement aussi aider Il suffit de comparer les résultats:

def test_dump(self):
    print yaml.dump([{'name': 'value'}, {'name2': 1}], explicit_start=True)
    print yaml.dump_all([{'name': 'value'}, {'name2': 1}])
0
Mikhail.Gorbulsky