Frage

Die PyYAML Paket lädt unmarkierte Strings als entweder Unicode oder str Objekte, je nach ihrem Inhalt.

Ich möchte Unicode-Objekte in meinem Programm verwenden (und leider nicht wechseln zu Python 3 nur noch) nicht.

Gibt es eine einfache Möglichkeit, PyYAML immer Strings Last Unicode-Objekte zu zwingen? Ich will nicht meine YAML mit !!python/unicode Tags Krempel.

# Encoding: UTF-8

import yaml

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

print yaml.load(menu)

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

Ich möchte: [u'spam', u'eggs', u'bacon', u'cr\xe8me br\xfbl\xe9e', u'spam']

War es hilfreich?

Lösung

Hier ist eine Version, die die PyYAML Handhabung von Strings, indem sie immer die Ausgabe unicode außer Kraft setzt. In Wirklichkeit ist dies wahrscheinlich das gleiche Ergebnis der andere Antwort habe ich geschrieben, außer kürzer (das heißt Sie noch sicherstellen müssen, dass die Strings in benutzerdefinierten Klassen zu unicode umgewandelt werden oder weitergegeben unicode Strings selbst, wenn Sie benutzerdefinierte Handler verwenden):

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

(Obige gibt [u'spam', u'eggs', u'bacon', u'cr\xe8me br\xfbl\xe9e', u'spam'])

Ich habe nicht getestet es auf LibYAML (die c-basierten Parsern), wie ich es allerdings nicht kompilieren konnte, so dass ich die andere Antwort verlassen würde, wie es war.

Andere Tipps

Hier ist eine Funktion, die Sie verwenden, nutzen könnten str mit unicode Typen aus dem decodierten Ausgang von PyYAML ersetzt werden:

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]})
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top