Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Строки 
:(
    Опции темы
Karadul
Дата 14.5.2012, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.5.2006

Репутация: нет
Всего: 1



1. Почему в "сырых" строках работают юникодовые последовательности, хотя байтовые не работают? Не совсем они, получается, "сырые".
Код

>>> ur"\User"
  File "<stdin>", line 1
SyntaxError: (unicode error) 'rawunicodeescape' codec can't decode bytes in position 0-1: truncated \uXXXX


2. 
Код

>>> unicode("ф")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xae in position 0: ordinal not in range(128)

Почему так?
PM MAIL   Вверх
VinniPuhh
Дата 15.5.2012, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 7.9.2011

Репутация: нет
Всего: нет



Цитата(Karadul @  14.5.2012,  09:52 Найти цитируемый пост)

Почему в "сырых" строках работают юникодовые последовательности, хотя байтовые не работают? Не совсем они, получается, "сырые".
Код

>>> ur"\User"
  File "<stdin>", line 1
SyntaxError: (unicode error) 'rawunicodeescape' codec can't decode bytes in position 0-1: truncated \uXXXX




А с чего ты взял что работают?
r"\User" - никаких ошибок, Python второй ветки создает str, длина 5 символов (обратный слэш - отдельный символ, как и ожидалось). В Python 2.x символы - однобайтовые, соотвественно это просто 5 байт подряд.
Обрати внимание, что r"\User" и "\User" - в данном случае одинаково, потому что управляющей последовательности \U в питоне нет.
А вот потом уже буквой u ты просишь его создать из объекта str объект unicode, причем заставляешь использовать raw codec.
Raw codec подразумевает, что последовательность "обратный слэш U четыре числа" будет перекодирована в один символ. Вот он и старается тебе перекодировать, но естественно ничего не выходит.
Если стоит задача перевести в юникод сочетание "обратный слэш User", то можно воспользоваться unicode(r'\User') - тогда подразумевается не создание строки unicode из группы байтов, а именно конвертация одного вида кодировки в другой.
В то же время ur'\u0410' ошибки не вызовет, это соответствует символу кириллицы "А"

И вот здесь переходим к второму вопросу. Если при создании ur'\u0410' ошибки не будет, то она запросто может появиться при отображении.
Дело в том, что python использует ascii по умолчанию для вывода и для ввода, а в ней просто нет такого символа ( http://www.asciitable.com/ ). Поэтому при попытке перекодирования строки "ф" в ascii, и здесь возникает исключение. Но ничто не мешает тебе сохранить например эту строку в файл, присвоить другой переменной, отдать в браузер пользователя если это например django и так далее.

Касательно твоего второго примера. Интерактивный шел питона использует локаль по умолчанию, для русской windows это Windows-1251. А функция unicode рассчитывает что ей подадут строку в кодировке по умолчанию, то есть ascii. Нужно прямо указать кодировку исходника, например unicode(x, 'Windows-1251')

Более четко можно посмотреть здесь, даже примеры похожие:
http://docs.python.org/howto/unicode.html#...unicode-support






Это сообщение отредактировал(а) VinniPuhh - 15.5.2012, 17:38
PM MAIL   Вверх
Karadul
Дата 16.5.2012, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.5.2006

Репутация: нет
Всего: 1



Цитата(VinniPuhh @  15.5.2012,  17:20 Найти цитируемый пост)
Если стоит задача перевести в юникод сочетание "обратный слэш User", то можно воспользоваться unicode(r'\User') - тогда подразумевается не создание строки unicode из группы байтов, а именно конвертация одного вида кодировки в другой.


Код

>>> unicode(r'\User\Документы')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x84 in position 6: ordinal not in range(128)

И что дальше? Указывать кодировку файла - неумное решение, т.к. во-первых тупо, а во-вторых, поменяется кодировка исходника - и программа перестанет работать.

Юникодные сырые строки, во-первых, нелогичны, т.к. одни эскейпы работают, а другие нет, а во-вторых, реальных юникодных сырых строк, получается, нет, все равно надо что-то костылить. И не вижу особого смысла указывать в юникодных строках символы через эскейп, т.к. их можно указать напряму (а исходники хранить в utf8), а во-вторых, есть же не сырые юникодные строки.

Цитата(VinniPuhh @  15.5.2012,  17:20 Найти цитируемый пост)
Касательно твоего второго примера. Интерактивный шел питона использует локаль по умолчанию, для русской windows это Windows-1251. А функция unicode рассчитывает что ей подадут строку в кодировке по умолчанию, то есть ascii. Нужно прямо указать кодировку исходника, например unicode(x, 'Windows-1251')

А не cp866 в консоли?
Тут немного неудобно как-то, неужели питон сам не знает кодировку своей сосноли?
PM MAIL   Вверх
VinniPuhh
Дата 17.5.2012, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 7.9.2011

Репутация: нет
Всего: нет



Цитата(Karadul @  16.5.2012,  13:05 Найти цитируемый пост)
А не cp866 в консоли?
Тут немного неудобно как-то, неужели питон сам не знает кодировку своей сосноли? 

Може ты и прав, може и cp866 - не уверен насчет именно 1251


Цитата(Karadul @  16.5.2012,  13:05 Найти цитируемый пост)

Тут немного неудобно как-то, неужели питон сам не знает кодировку своей косноли? 

Не то чтобы "своей", скорее системной (stdin/stdout). 
По идее да, можно было бы системным API выяснить какая там кодировка по умолчанию.
Я думаю что разработчики не сделали такого, чтобы избежать проблем при конструкциях
myprg.exe file1 > pyhton myscript.py
и тому подобным.

Цитата(Karadul @  16.5.2012,  13:05 Найти цитируемый пост)

И что дальше? Указывать кодировку файла - неумное решение, т.к. во-первых тупо, а во-вторых, поменяется кодировка исходника - и программа перестанет работать.


А вот тут (естественно imho) ты в корне не прав по идеологии. Ты  задаешь литерал, значение которого используется в программе.
Посмотри с точки зрения интерпретатора: Как понять, что именно (в байтовом представлении) ты имел в виду?
Логично есть такие пути:
 1. Задавать литерал явно в байтовом представлении  (\u0514\u0213\u2231)
 2. Указать явно, каким образом переводить набранное в редакторе в это представление (# -*- coding: utf-8 -*-)
 3. Запретить набирать в редакторе неоднозначные символы (SyntaxError: Non-ASCII character '\xd1' in file test.py on line 1, but no encoding declared;)
 4. Договориться, что всегда использовать определенный алгоритм перевода. (Пока в сообществе Python не договорились smile )

Как видишь, три из четырех придуманных мной путей питон поддерживает.
Как раз наоборот, если не указывать кодировку явно, то будет эффект "поменяется кодировка исходника - и программа перестанет работать" - ведь вместо предполагаемого "Документы" будет преобразовано в крокозябры.

Я бы решал вопрос так:

Код

# -*- coding: utf-8 -*-
path = u'\\User\\Документы'




PM MAIL   Вверх
Karadul
Дата 17.5.2012, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 378
Регистрация: 18.5.2006

Репутация: нет
Всего: 1



Цитата(VinniPuhh @  17.5.2012,  12:10 Найти цитируемый пост)
А вот тут (естественно imho) ты в корне не прав по идеологии. 

Мы друг друга не поняли, я имел в виду указывать в unicode() вторым параметром кодировку файла. Указывать в файле кодировку считаю - правильно, хорошо бы жавоидам это перенять.


Цитата(Karadul @  16.5.2012,  13:05 Найти цитируемый пост)
сосноли? 

Цитата(VinniPuhh @  17.5.2012,  12:10 Найти цитируемый пост)
косноли? 

Сам переправил? smile

Цитата(VinniPuhh @  17.5.2012,  12:10 Найти цитируемый пост)
Цитата(Karadul @  16.5.2012,  13:05 Найти цитируемый пост)

Тут немного неудобно как-то, неужели питон сам не знает кодировку своей косноли? 

Не то чтобы "своей", скорее системной (stdin/stdout). 
По идее да, можно было бы системным API выяснить какая там кодировка по умолчанию.
Я думаю что разработчики не сделали такого, чтобы избежать проблем при конструкциях
myprg.exe file1 > pyhton myscript.py
и тому подобным.

Кодировка сосноли в данном случае - кодировка исходника, т.к. вместо исходного файла - сосноль. Может быть, не хотели ошибок из-за того, что вместо кодировки бы автоматически подставлялась кодировка исходника там где надо и где не надо.

Кстати, в 3.х стоковые литералы по умолчанию юникодные. Решает много проблем. И вообще, в 2.х юникод - больное место. Видите ли, в 2012 году, когда даже линупс юникод осилил, а 9х уже похоронили, программы не работают, если пути, где лежат они или файлы, с которыми они работают, содержат не-аски символы. А все потому, что у девелоперов все работало.

Цитата(VinniPuhh @  17.5.2012,  12:10 Найти цитируемый пост)
Я бы решал вопрос так:

Не, я в курсе, что так можно, но я ничего эскейпить не хочу.

Короче, баг налицо, вопрос, будут ли его править. В 3.х, говорят, все работает.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0744 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.