PyYAML: dumping sans étiquettes
Question
Je
>>> import yaml
>>> yaml.dump(u'abc')
"!!python/unicode 'abc'\n"
Mais je veux
>>> import yaml
>>> yaml.dump(u'abc', magic='something')
'abc\n'
Quelle magie forces de marquage ne param?
La solution
Vous pouvez utiliser safe_dump
au lieu de dump
. Il suffit de garder à l'esprit que ce ne sera pas en mesure de représenter des objets Python arbitraires alors. En outre, lorsque vous load
le YAML, vous obtiendrez un objet str
au lieu de unicode
.
Autres conseils
Que diriez-vous ceci:
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 le dumping des objets unicode fonctionnent comme des objets de dumping 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'
Vous avez besoin d'une nouvelle classe de sniffeur qui fait tout la norme classe Dumper ne remplace mais les Representers 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)
Ce qui nous amène à
>>> 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"]
D'accord, je suis toujours perplexe sur la façon de garder ce joli.
>>> print u'abc\xe7'
abcç
Et il casse un yaml.load plus tard ()
>>> 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ç
peu plus d'une excellente réponse de interjay, vous pouvez garder votre unicode sur un reload si vous prenez soin de vos encodages de 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 contenu 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 assez sûr que safe_load / safe_dump est là où je veux être de toute façon.
Je viens juste de commencer avec Python et YAML, mais probablement cela peut 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}])