2009-12-23 4 views

risposta

69

È possibile utilizzare safe_dump anziché dump. Ricorda che non sarà in grado di rappresentare oggetti Python arbitrari. Inoltre, quando si load YAML, si otterrà un oggetto str anziché unicode.

+0

safe_dump sembra forzare un '...' alla fine, ma è facile da risolvere –

+0

Che dire di 'dump_all'? – ATOzTOA

+0

@ATOzTOA Non sono sicuro di cosa stai chiedendo, ma c'è anche 'safe_dump_all'. – interjay

13

ne dite di questo:

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) 

questo sembra consistere di dumping oggetti Unicode funzionano allo stesso modo come oggetti str di dumping per me (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

Questo funziona per i casi di base, ma in alcuni casi incasina i dati. Inoltre, dovresti menzionare nella risposta che la funzione è chiamata su 'yaml' e non su un oggetto. – ATOzTOA

3

Hai bisogno di un nuova classe dumper che fa tutto la classe Dumper normale fa, ma ignora le representers per str e 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) 

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

Certo, sono ancora perplesso su come mantenere questa bella.

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

E si rompe un yaml.load successiva()

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

Ho appena iniziato con Python e YAML, ma probabilmente questo può anche aiutare. Basta confrontare le uscite:

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

piccola aggiunta al di interjay risposta eccellente, è possibile mantenere l'unicode su una ricarica se si prende cura dei vostri codifiche di file.

# -*- 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 contenuti nel mio editor:

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

uscite di stampa:

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

Inoltre, dopo aver letto http://nedbatchelder.com/blog/201302/war_is_peace.html Sono abbastanza sicuro che safe_load/safe_dump è dove voglio essere comunque.