Как преобразовать объекты unicode в обычные объекты в Python

#python #unicode

#python #юникод

Вопрос:

В настоящее время у меня есть deep object, и все это в unicode (к сожалению).

Я дошел до того, что переменная будет либо dict, либо bool. В этом случае я делаю

if type( my_variable ) is BooleanType:

Но это не срабатывает, потому что тип фактически является Unicode для всех значений.

Как мне преобразовать этот объект unicode в обычный объект, чтобы я мог правильно прочитать тип, не уничтожая данные?

Спасибо!

Вот результат print(repr(переменная)). Это показывает, что Bools не являются unicode (в отличие от того, что я сделал сначала), но все еще доставляют мне проблемы.

 {u'forms': {u'financing': {u'view': True, u'delete': True}, u'employment': {u'view': True, u'delete': True}, u'service': {u'view': True, u'delete': True}}, u'content': {u'articles': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'slideshow': {u'edit': True, u'view': True}, u'pages': {u'edit': True, u'add': True, u'view': True, u'delete': True}}, u'people': {u'edit': True, u'sort-staff': True, u'sort-riders': True, u'add': True, u'delete': True, u'view': True}, u'events': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'settings': {u'edit': True, u'view': True}}
  

Комментарии:

1. Я не вижу, как dict или bool могут быть в формате unicode — конечно, может быть только строка. Можете ли вы показать пример?

2. Не могли бы вы, пожалуйста, выполнить print(repr(my_variable)) и скопировать-вставить его выходные данные в ваш вопрос, чтобы мы лучше понимали, что нужно преобразовать?

3. кашель вы должны использовать isinstance и bool вместо type() и types. BooleanType , и это без исправления полной дурацкой небезопасности отсутствия представления о том, что такое объект. Конечно, python динамически типизируется, но вы должны избегать ввода…

4. @neil Я думаю, что это ключи dict, которые являются unicode. @pts Готово

5. -1: «все еще доставляет мне проблемы». Бесполезно. Неинформативно. Что это значит? Что вы пытаетесь сделать? «переменная будет либо dict, либо bool» Вообще не имеет никакого смысла. Очевидно, вы делаете что-то очень неправильное. Что вы пытаетесь сделать? Пожалуйста, предоставьте некоторый фактический код и фактическое сообщение об ошибке.

Ответ №1:

Не используйте, type если вы действительно не уверены, что хотите этого.

В этом случае вы этого не делаете — особенно проверяя bool , учитывая гибкость Python в отношении того, что можно рассматривать как логическое значение! Например, что, если вам дадут None ? Как насчет пустой строки? Как насчет [] ?

Решением этой проблемы является использование абстрактных базовых классов (ABC), которые позволяют вам точно указать, что объект должен уметь делать, вместо того, что type собой представляет. collections Модуль поставляется с кучей таких:

 import collections
if isinstance( ..., collections.MutableMapping ):
    ...
  

Это разрешает все, что «похоже на словарь», так что вы сохраняете полиморфизм. Если вам нужна более тщательная спецификация («Я хочу __getitem__ и __delitem__ , но не обязательно __setitem__ !»), вы можете написать свою собственную — для начала смотрите определение ABCs в исходном коде модуля collections.

Вы уверены, что вам нужна эта функциональность? Если вы делаете это правильно (с помощью ABCS), это неплохая идея, но это не значит, что вы должны злоупотреблять ею!


Редактировать: я не уверен, что вы понимаете, что такое Unicode или как Python обрабатывает его. Это одно из основных различий между Python 2.x и Python 3.x, который вы используете?

Повторно отредактировать: Ах, хорошо, вы используете Python 2.x, и у вас есть словарь со строковыми ключами Unicode. Я не уверен, что вы делали, что вызвало проблему, поскольку строки Unicode работают в основном так же, как обычные строки. MutableMapping Проверка, приведенная выше, будет работать нормально.

Комментарии:

1. Лучше, но лучше всего всегда избегать ситуации, когда вашим объектом может быть одна из двух вещей. Это хорошее решение серьезной проблемы, если вы понимаете, что я имею в виду.

2. Это серьезная проблема, но не обязательно неизбежная. Иногда вам просто нужно различать некоторые возможности (строка или список строк являются общими, скажем, для удаления файлов).

3. Буду ли я использовать ту же концепцию для преобразования unicode int в int? Я попробовал int (переменная)

4. @Shane: Я не думаю, что вы поняли сообщение выше — не существует такого понятия, как «unicode int» . Вы читали одно из руководств по Python unicode?

5. (Кто-то что-то исправил в сообщении выше, но я редактировал его в то же время и переписал ваше изменение. Не могли бы вы это исправить? Спасибо =))

Ответ №2:

Возможно, вам следует узнать о модуле pretty print, поскольку он заставляет вас проверять вещи (даже я согласен, что вы ставите себя в тупик. Обычно это происходит как рекурсия результата с неправильным видом результата, например, при выполнении append, когда вы должны выполнить extend для списка)

Здесь содержимое вашей переменной довольно напечатано:

 {u'content': {u'articles': {u'add': True,
                            u'delete': True,
                            u'edit': True,
                            u'view': True},
              u'pages': {u'add': True,
                         u'delete': True,
                         u'edit': True,
                         u'view': True},
              u'slideshow': {u'edit': True, u'view': True}},
 u'events': {u'add': True, u'delete': True, u'edit': True, u'view': True},
 u'forms': {u'employment': {u'delete': True, u'view': True},
            u'financing': {u'delete': True, u'view': True},
            u'service': {u'delete': True, u'view': True}},
 u'people': {u'add': True,
             u'delete': True,
             u'edit': True,
             u'sort-riders': True,
             u'sort-staff': True,
             u'view': True},
 u'settings': {u'edit': True, u'view': True}}
  

Из этого очевидно, что у вас есть только значение True, а не False. Каков вариант использования этих значений? Почему, например, вы не используете set: {u’add’, u’delete’, u’edit’, u’sort-riders’, …}?

 from pprint import pprint

def alternative(yourdict):
    for key in yourdict:
        if yourdict[key] is True:
            yield set(yourdict.keys())
            break
        else:
            yield tuple((key,tup) for tup in alternative(yourdict[key]))

my_variable = {u'forms': {u'financing': {u'view': True, u'delete': True}, u'employment': {u'view': True, u'delete': True}, u'service': {u'view': True, u'delete': True}}, u'content': {u'articles': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'slideshow': {u'edit': True, u'view': True}, u'pages': {u'edit': True, u'add': True, u'view': True, u'delete': True}}, u'people': {u'edit': True, u'sort-staff': True, u'sort-riders': True, u'add': True, u'delete': True, u'view': True}, u'events': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'settings': {u'edit': True, u'view': True}}
pprint(my_variable)

print 50 * '-'
print 'Alternative datastructure'
pprint(tuple(alternative(my_variable)))