Ответ 1
Рекурсия выглядит как способ пойти сюда, но если вы на python 2.xx, вы хотите проверить unicode
, а не str
(тип str
представляет собой строку байтов, а unicode
введите строку символов Юникода, а не наследуется от другой, и это строки типа Unicode, которые отображаются в интерпретаторе с au перед ними).
Там также немного синтаксическая ошибка в вашем опубликованном коде (конечный elif:
должен быть else
), и вы не возвращаете ту же структуру в том случае, когда ввод является либо словарем, либо списком. (В случае словаря вы возвращаете преобразованную версию финального ключа, а в случае списка вы возвращаете преобразованную версию конечного элемента. Правильно!)
Вы также можете сделать свой код симпатичным и Pythonic с помощью понятий.
Вот, вот что я бы рекомендовал:
def convert(input):
if isinstance(input, dict):
return {convert(key): convert(value) for key, value in input.iteritems()}
elif isinstance(input, list):
return [convert(element) for element in input]
elif isinstance(input, unicode):
return input.encode('utf-8')
else:
return input
Одна последняя вещь. Я изменил encode('ascii')
на encode('utf-8')
. Мое рассуждение таково: любая строка юникода, содержащая только символы в наборе символов ASCII, будет представлена одной и той же строкой байта при кодировании в ASCII, как при кодировании в utf-8, поэтому использование utf-8 вместо ASCII не может сломать что-либо и изменение будет невидимым до тех пор, пока строки unicode, с которыми вы имеете дело, используют только символы ASCII. Однако это изменение расширяет область действия функции, чтобы иметь возможность обрабатывать строки символов из всего набора символов Юникода, а не только ASCII, если такая необходимость когда-либо понадобится.