(ошибка Юникода) кодек 'unicodeescape' не может декодировать байт-строку с помощью 'u'
написание моего кода для Python 2.6, но с Python 3 в виду, я думал, что это была хорошая идея поставить
from __future__ import unicode_literals
в верхней части некоторых модулей. Другими словами, Я прошу неприятностей (чтобы избежать их в будущем), но я могу упустить некоторые важные знания здесь. Я хочу иметь возможность передать строку, представляющую путь к файлу, и создать экземпляр объекта, простого как
MyObject('H:unittests')
на Python 2.6, это работает просто отлично, нет необходимо использовать двойные косые черты или необработанную строку, даже для каталога, начинающегося с 'u..'
, что именно то, что я хочу. В __init__
метод я убеждаюсь, что все одиночные события интерпретируются как"
', в том числе перед специальными символами, как в
a
, b
, f
,n
, r
, t
и v
(всего x
остается проблема). Также декодирование данной строки в unicode с использованием (локальной) кодировки работает, как ожидалось.
подготовка для Python 3.x, имитируя мою фактическую проблему в Редакторе (начиная с чистой консоли в Python 2.6), происходит следующее:
>>> 'u'
'u'
>>> r'u'
'u'
(хорошо, пока здесь:'u'
кодируется консолью с использованием локальной кодировки)
>>> from __future__ import unicode_literals
>>> 'u'
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: end of string in escape sequence
другими словами, строка (unicode) не интерпретируется как unicode вообще, и она не декодируется автоматически с локальной кодировкой. Даже на "сырые" строки:
>>> r'u'
SyntaxError: (unicode error) 'rawunicodeescape' codec can't decode bytes in position 0-1: truncated uXXXX
же для u'u'
:
>>> u'u'
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-1: end of string in escape sequence
кроме того, я ожидаю, что isinstance(str(''), unicode)
вернуться True
(чего он не делает), потому что импорт unicode_literals должен сделать все строковые типы unicode. (edit:), потому что в Python 3, все строки являются последовательностями символов Unicode, я бы ожидал str(''))
для возврата такой строки unicode и type(str(''))
как <type 'unicode'>
и <type 'str'>
(потому что все строки являются unicode), но также понимают, что <type 'unicode'> is not <type 'str'>
. Путаница все вокруг...
вопросы
- как я могу лучше всего передать строки, содержащие'
u
'? (не написав"u
') - тут
from __future__ import unicode_literals
действительно реализовать все Python 3. связанные изменения unicode, чтобы я получил полную среду строк Python 3?
изменить:
В Python 3, <type 'str'>
является объектом Unicode и <type 'unicode'>
просто не существует. В моем случае я хочу написать код для Python 2(.6) это будет работать в Python 3. Но когда я ... --32-->, я не могу проверить, если строка <type 'unicode'>
потому что:
- предполагаю
unicode
не является частью пространства имен - если
unicode
является частью пространства имен, в строке<type 'str'>
по-прежнему unicode, когда он создается в том же модуле -
type(mystring)
всегда будет возвращать<type 'str'>
для литералов unicode в Python 3
мои модули используются для кодирования в 'utf-8' с помощью # coding: UTF-8
комментарий в топ, в то время как мой locale.getdefaultlocale()[1]
возвращает 'cp1252'. Так что если я позвоню MyObject('çça')
с моей консоли он кодируется как "cp1252" в Python 2 и в "utf-8" при вызове MyObject('çça')
из модуля. В Python 3 он не будет закодирован, а будет литералом unicode.
edit:
я оставил надежду на то, что мне позволят избежать использования " " перед u
(или x
если на то пошло). Также я понимаю ограничения импорта unicode_literals
. Однако многих возможных комбинации передачи строки из модуля в консоль и наоборот с каждой другой кодировкой, а поверх этого импорта unicode_literals
или нет и Python 2 против Python 3, заставил меня захотеть создать обзор путем фактического тестирования. Отсюда и таблица ниже.
другими словами, type(str(''))
не возвращает <type 'str'>
в Python 3, но <class 'str'>
, и все проблемы Python 2, похоже, избегаются.
4 ответов
насколько я знаю, все, что from __future__ import unicode_literals
не все строковые литералы типа unicode вместо типа string. То есть:
>>> type('')
<type 'str'>
>>> from __future__ import unicode_literals
>>> type('')
<type 'unicode'>
но str
и unicode
еще разные типы, и они ведут себя так же, как и раньше.
>>> type(str(''))
<type 'str'>
всегда, имеет str
тип.
о r'\u'
вопрос, это по дизайну, так как это эквивалентно ru '\u ' без unicode_literals
. Из документов:
когда префикс' r 'или' R' используется в сочетании с префиксом " u " или "U", затем escape-последовательности \uxxxxxx и \UXXXXXXXX обрабатываются, а все остальные обратные косые черты остаются в строке.
вероятно, из того, как лексический анализатор работал в серии python2. В python3 он работает так, как вы (и я) ожидали бы.
вы можете ввести обратную косую черту дважды, а затем \u
не будет интерпретироваться, но вы получите два раза подряд!
обратные косые черты могут быть escaped с предыдущей обратной косой чертой; однако оба остаются в строке
>>> ur'\u'
u'\\u'
Итак, ИМХО, у вас есть два простых варианта:
-
не используйте необработанные строки и избегайте обратных косых черт (совместимо с python3):
'H:\unittests'
-
будьте слишком умны и воспользуйтесь кодовыми точками unicode (не совместимость с python3):
r'H:\u005cunittests'
для меня этот вопрос редакции не в курсе, в данном случае numpy
исправления :
conda install -f numpy
когда вы пишете строковые литералы, содержащие обратные косые черты, такие как пути (в Windows) или регулярные выражения, используйте необработанные строки. Для этого они и существуют.