pyyaml: Dumping ohne Tags

71

ich habe

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

Aber ich möchte

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

Welcher magische Parameter erzwingt kein Markieren?

Paul Tarjan
quelle

Antworten:

93

Sie können safe_dumpanstelle von verwenden dump. Denken Sie daran, dass es dann keine beliebigen Python-Objekte darstellen kann. Wenn Sie loaddie YAML verwenden, erhalten Sie strstattdessen ein Objekt anstelle von unicode.

Interjay
quelle
safe_dump scheint am Ende ein '...' zu erzwingen, aber das ist leicht zu beheben
Paul Tarjan
@ATOzTOA Ich bin nicht sicher, was Sie fragen, aber es gibt safe_dump_allauch.
Interjay
@interjay Ja, richtig. Ich habe das versucht, aber ich habe ein Objekt, keine Zeichenfolge. Macht Sinn.
ATOzTOA
19

Wie wäre es damit:

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)

Dies scheint dazu zu führen, dass das Dumping von Unicode-Objekten genauso funktioniert wie das Dumping von str-Objekten für mich (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'
Michał Marczyk
quelle
1
Dies funktioniert in einfachen Fällen, bringt jedoch in einigen Fällen die Daten durcheinander. Außerdem sollten Sie in der Antwort erwähnen, dass die Funktion aufgerufen wird yamlund nicht für ein Objekt.
ATOzTOA
4

Sie benötigen eine neue Dumper-Klasse, die alles tut, was die Standard-Dumper-Klasse tut, aber die Repräsentanten für str und unicode überschreibt.

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)

Was dazu führt

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

Zugegeben, ich bin immer noch ratlos, wie ich das hübsch halten soll.

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

Und es bricht eine spätere 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ç
Chris Dukes
quelle
2

Sie können Ihren Unicode beim erneuten Laden beibehalten, wenn Sie sich um Ihre Dateicodierungen kümmern.

# -*- 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 Inhalt in meinem Editor:

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

Druckausgaben:

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

Nachdem ich http://nedbatchelder.com/blog/201302/war_is_peace.html gelesen habe, bin ich mir ziemlich sicher, dass safe_load / safe_dump sowieso der Ort ist, an dem ich sein möchte.

JL Peyret
quelle
0

Ich habe gerade mit Python und YAML angefangen, aber wahrscheinlich kann dies auch helfen. Vergleichen Sie einfach die Ergebnisse:

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