Как вынудить PyYAML к строкам загрузки как unicode объекты?

Пакет PyYAML загружает неотмеченные строки или как unicode или как объекты ул., в зависимости от их содержания.

Я хотел бы использовать объекты unicode всюду по своей программе (и, к сожалению, просто еще не может переключиться на Python 3).

Существует ли простой способ вынудить PyYAML к всегда строковым объектам unicode загрузки? Я не хочу создавать помехи своему YAML !!python/unicode теги.

# Encoding: UTF-8

import yaml

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

print yaml.load(menu)

Вывод: ['spam', 'eggs', 'bacon', u'cr\xe8me br\xfbl\xe9e', 'spam']

Я хотел бы: [u'spam', u'eggs', u'bacon', u'cr\xe8me br\xfbl\xe9e', u'spam']

30
задан Petr Viktorin 23 May 2010 в 10:30
поделиться

2 ответа

Вот версия, которая отменяет обработку строк PyYAML, всегда выводя unicode . На самом деле, это, вероятно, тот же результат, что и другой ответ, который я опубликовал, за исключением более короткого (т.е. вам все равно нужно убедиться, что строки в пользовательских классах преобразованы в unicode или переданы unicode строки сами, если вы используете собственные обработчики):

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

(Вышеупомянутое дает [u'spam ', u'eggs', u'bacon ', u'cr \ xe8me br \ xfbl \ xe9e', u'spam ' ] )

Я не тестировал его на LibYAML (синтаксический анализатор на основе c), поскольку я не смог его скомпилировать, поэтому оставлю другой ответ как есть.

25
ответ дан 28 November 2019 в 00:22
поделиться

Вот функция, которую можно использовать для замены str на типы unicode из декодированного вывода 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]})
3
ответ дан 28 November 2019 в 00:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: