Подтвердить что ты не робот

(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, похоже, избегают.

4b9b3361

Ответ 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) или регулярные выражения, используйте необработанные строки. Для чего они предназначены.