(unicode error) '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, все строки являются последовательностями символов Юникода, я ожидал бы str(''))
верните такую строку unicode, а type(str(''))
- как <type 'unicode'>
, так и <type 'str'>
(потому что все строки являются юникодами), но также понимают, что <type 'unicode'> is not <type 'str'>
. Путаница вокруг...
Вопросы
- Как лучше всего передать строки, содержащие '
\u
'? (без записи '\\u
')
- действительно ли
from __future__ import unicode_literals
действительно реализует все изменения в Unicode, связанные с Python 3. Таким образом, я получаю полную строковую строку Python 3?
изменить:
В Python 3 <type 'str'>
является объектом Unicode и <type 'unicode'>
просто не существует. В моем случае я хочу написать код для Python 2 (.6), который будет работать на Python 3. Но когда я import unicode_literals
, я не могу проверить, имеет ли строка <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.
изменить:
Я отказался от того, что мне разрешено использовать '\' до u
(или x
, если на то пошло). Также я понимаю ограничения импорта unicode_literals
. Тем не менее, многие возможные комбинации передачи строки из модуля в консоль и vica versa с каждой различной кодировкой, а также над тем, что импортирование unicode_literals
или нет, и Python 2 vs Python 3, заставило меня захотеть создать обзор фактическое тестирование. Отсюда приведенная ниже таблица. ![enter image description here]()
Другими словами, type(str(''))
не возвращает <type 'str'>
в Python 3, а <class 'str'>
, и все проблемы Python 2, похоже, избегают.
Ответы
Ответ 1
AFAIK, все, что from __future__ import unicode_literals
делает, это сделать все строковые литералы типа unicode, а не тип строки. То есть:
>>> 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-последовательности\uXXXX и \UXXXXXXXX обрабатываются, а все остальные обратные косые черты остаются в строке.
Возможно, из-за того, как лексический анализатор работал в серии python2. В python3 он работает так, как вы (и я) ожидаем.
Вы можете ввести обратную косую черту дважды, а затем \u
не будет интерпретироваться, но вы получите две обратные косые черты!
Обратные косые черты могут быть экранированы с предыдущей обратной косой чертой; однако оба они остаются в строке
>>> ur'\\u'
u'\\\\u'
Итак, IMHO, у вас есть два простых варианта:
-
Не используйте необработанные строки и избегайте обратных косых черт (совместимых с python3):
'H:\\unittests'
-
Будьте слишком умны и используйте кодовые страницы unicode ( не, совместимые с python3):
r'H:\u005cunittests'
Ответ 2
Для меня эта проблема связана с версией, не обновленной, в данном случае numpy
Чтобы исправить:
conda install -f numpy
Ответ 3
Я пробую это на Python 3:
import os
os.path.abspath( "yourPath" )
и это сработало!
Ответ 4
Когда вы пишете строковые литералы, содержащие обратные косые черты, такие как пути (в Windows) или регулярные выражения, используйте необработанные строки. Для чего они предназначены.