Написав мой код для 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, заставило меня захотеть создать обзор фактическое тестирование. Отсюда приведенная ниже таблица.
Другими словами, type(str(''))
не возвращает <type 'str'>
в Python 3, а <class 'str'>
, и все проблемы Python 2, похоже, избегают.