Question

Les charges de paquet PyYAML chaînes non marquées comme des objets soit unicode ou str, en fonction de leur contenu.

Je voudrais utiliser des objets unicode tout au long de mon programme (et, malheureusement, ne peut pas passer à Python 3 pour l'instant).

Yat-il un moyen facile de forcer PyYAML à toujours les objets de unicode de charge? Je ne veux pas encombrer mon YAML avec des balises !!python/unicode.

# Encoding: UTF-8

import yaml

menu= u"""---
- spam
- eggs
- bacon
- crème brûlée
- spam
"""

print yaml.load(menu)

Sortie: ['spam', 'eggs', 'bacon', u'cr\xe8me br\xfbl\xe9e', 'spam']

Je voudrais: [u'spam', u'eggs', u'bacon', u'cr\xe8me br\xfbl\xe9e', u'spam']

Était-ce utile?

La solution

Voici une version qui remplace la manipulation PyYAML des chaînes en produisant toujours unicode. En réalité, ce qui est probablement le résultat identique de l'autre réponse que j'ai posté sauf plus court (à savoir vous encore devez vous assurer que les chaînes dans les classes personnalisées sont converties en unicode ou passés vous chaînes de unicode si vous utilisez des gestionnaires personnalisés):

# -*- 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
""")

(Le ci-dessus donne [u'spam', u'eggs', u'bacon', u'cr\xe8me br\xfbl\xe9e', u'spam'])

Je ne l'ai pas testé sur LibYAML (l'analyseur à base c) que je ne pouvais pas le compiler, donc je vais laisser l'autre réponse qu'il était.

Autres conseils

Voici une fonction que vous pouvez utiliser à utiliser pour remplacer str avec les types de unicode de la sortie décodée 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]})
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top