instalar - read yaml python
¿Cómo obligar a PyYAML a cargar cadenas como objetos Unicode? (2)
Aquí hay una función que podría usar para reemplazar str
con tipos unicode
de la salida descodificada de PyYAML
:
def make_str_unicode(obj):
t = type(obj)
if t in (list, tuple):
if t == tuple:
# Convert to a list if a tuple to
# allow assigning to when copying
is_tuple = True
obj = list(obj)
else:
# Otherwise just do a quick slice copy
obj = obj[:]
is_tuple = False
# Copy each item recursively
for x in xrange(len(obj)):
obj[x] = make_str_unicode(obj[x])
if is_tuple:
# Convert back into a tuple again
obj = tuple(obj)
elif t == dict:
for k in obj:
if type(k) == str:
# Make dict keys unicode
k = unicode(k)
obj[k] = make_str_unicode(obj[k])
elif t == str:
# Convert strings to unicode objects
obj = unicode(obj)
return obj
print make_str_unicode({''blah'': [''the'', ''quick'', u''brown'', 124]})
El paquete PyYAML carga cadenas no marcadas como objetos unicode o str, dependiendo de su contenido.
Me gustaría usar objetos Unicode en mi programa (y, lamentablemente, todavía no puedo cambiar a Python 3).
¿Existe una manera fácil de forzar a PyYAML a que siempre las cadenas carguen objetos Unicode? No quiero saturar mi YAML con etiquetas !!python/unicode
.
# Encoding: UTF-8
import yaml
menu= u"""---
- spam
- eggs
- bacon
- crème brûlée
- spam
"""
print yaml.load(menu)
Salida: [''spam'', ''eggs'', ''bacon'', u''cr/xe8me br/xfbl/xe9e'', ''spam'']
Me gustaría: [u''spam'', u''eggs'', u''bacon'', u''cr/xe8me br/xfbl/xe9e'', u''spam'']
Aquí hay una versión que anula el manejo PyYAML de las cadenas al generar siempre unicode
. En realidad, este es probablemente el resultado idéntico de la otra respuesta que publiqué, excepto la más corta (es decir, aún debe asegurarse de que las cadenas en las clases personalizadas se conviertan a unicode
o se pasen a unicode
cadenas de unicode
si utiliza controladores personalizados):
# -*- coding: utf-8 -*-
import yaml
from yaml import Loader, SafeLoader
def construct_yaml_str(self, node):
# Override the default string handling function
# to always return unicode objects
return self.construct_scalar(node)
Loader.add_constructor(u''tag:yaml.org,2002:str'', construct_yaml_str)
SafeLoader.add_constructor(u''tag:yaml.org,2002:str'', construct_yaml_str)
print yaml.load(u"""---
- spam
- eggs
- bacon
- crème brûlée
- spam
""")
(Lo anterior da [u''spam'', u''eggs'', u''bacon'', u''cr/xe8me br/xfbl/xe9e'', u''spam'']
)
No lo he probado en LibYAML
(el analizador basado en C) porque no pude compilarlo, así que dejaré la otra respuesta como estaba.