2009-12-23 14 views
53

tengoPyYAML: dumping sin etiquetas

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

Pero quiero

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

¿Qué fuerzas param magia sin el etiquetado?

Respuesta

69

Puede usar safe_dump en lugar de dump. Solo tenga en cuenta que no podrá representar objetos arbitrarios de Python en ese momento. Además, cuando load el YAML, obtendrá un objeto str en lugar de unicode.

+0

safe_dump parece forzar un '...' al final, pero eso es fácil de arreglar –

+0

¿Qué pasa con 'dump_all'? – ATOzTOA

+0

@ATOzTOA No estoy seguro de lo que estás preguntando, pero también está 'safe_dump_all'. – interjay

13

¿Qué tal esto:

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) 

Esto parece tener de dumping objetos Unicode funcionan igual que los objetos str de dumping para mí (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' 
+1

Esto funciona para casos básicos, pero daña los datos en algunos casos. Además, debe mencionar en la respuesta que la función se llama en 'yaml' y no en un objeto. – ATOzTOA

3

necesita una nueva clase de descargador que hace todo lo que la clase estándar Volquete hace pero anula los representers para str y 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) 

que nos lleva a

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

Por supuesto, todavía estoy perplejo sobre cómo mantener este bonito.

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

Y se rompe un yaml.load tarde()

>>> 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ç 
0

Acabo de empezar con Python y YAML, pero probablemente esto también puede ayudar. Basta con comparar las salidas:

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

pequeña adición a interjay de excelente respuesta, puede mantener su Unicode en una recarga si se toma el cuidado de sus codificaciones de archivo.

# -*- 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 contenidos en mi editor:

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

salidas de impresión:

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

Además, después de leer http://nedbatchelder.com/blog/201302/war_is_peace.html Estoy bastante seguro de que safe_load/safe_dump es donde quiero estar de todos modos.

Cuestiones relacionadas