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