Вот как это оно ухитряется
Sep. 17th, 2009 01:41 amОбнаружил в своем питоновском скрипте проблему - если вывод направлен на терминал, оно работает нормально. Если вывод переназначен в пайп или файл, то делает шлеп по первому же русскому символу, говорит что не может его перекодировать кодеком ascii.
import sys
print "stdout=",sys.stdout.encoding
print "stdin=",sys.stdin.encoding
показывает, что у непереназначенного стандартного файла encoding соответствует текущей локали,
а у переназначенного - None.
Если сделать
import locale
locale.setlocale(locale.LC_CTYPE,'')
то кодировка None оказывается вполне совпадающей с тем, что ожидалось, и русские буквы нормально выводятся в пайп или файл. Т.е. собственно вызов setlocale проблему решает.
Вопрос в том - как этот гад ползучий ухитряется узнать в какой кодировке должны быть stdin и stdout, не делая вызовов setlocale и nl_langinfo(CODESET)?
В исходники его мне лезть лень. Но я знаю что меня читают минимум два человека, которые туда лазили. Может быть вы знаете ответ?
P.S. Все гораздо хуже. А вот если в исходнике написано # -*- coding: что-нибудь -*-
и что-то вроде print u'Привет' то просто установка локали в случае переназначения ввода-вывода
не помогает. Надо sys.setdefaultencoding делать. А эта функция доступна только при явном отключении загрузки модуля site (опция -S). Блин, я убью этого голландца.
import sys
print "stdout=",sys.stdout.encoding
print "stdin=",sys.stdin.encoding
показывает, что у непереназначенного стандартного файла encoding соответствует текущей локали,
а у переназначенного - None.
Если сделать
import locale
locale.setlocale(locale.LC_CTYPE,'')
то кодировка None оказывается вполне совпадающей с тем, что ожидалось, и русские буквы нормально выводятся в пайп или файл. Т.е. собственно вызов setlocale проблему решает.
Вопрос в том - как этот гад ползучий ухитряется узнать в какой кодировке должны быть stdin и stdout, не делая вызовов setlocale и nl_langinfo(CODESET)?
В исходники его мне лезть лень. Но я знаю что меня читают минимум два человека, которые туда лазили. Может быть вы знаете ответ?
P.S. Все гораздо хуже. А вот если в исходнике написано # -*- coding: что-нибудь -*-
и что-то вроде print u'Привет' то просто установка локали в случае переназначения ввода-вывода
не помогает. Надо sys.setdefaultencoding делать. А эта функция доступна только при явном отключении загрузки модуля site (опция -S). Блин, я убью этого голландца.
no subject
Date: 2009-09-16 10:42 pm (UTC)no subject
Date: 2009-09-17 05:39 am (UTC)no subject
Date: 2009-09-17 06:23 am (UTC)...
Attitudes toward Python
* 1995 - eShop - What is python?
* 1996 - eShop - Python is great and making us successful
* 1997 - MS (acquired eShop) - Shipped embedded python in their product
* 1998 - MS - We are using python? That was a "prototype". Let's re-write it. (The re-write in .asp was slower)
* 2001 - Collabnet - We don't use python
* 2003 - Collabnet - Write that in python
* 2005 - Google - Of course we use python
В поисках как-то выносило на вполне змеиные страницы Гугла.
(no subject)
From:no subject
Date: 2009-09-16 10:43 pm (UTC)Ты же знаешь, что Unicode в py2 - это afterthought.
no subject
Date: 2009-09-17 05:38 am (UTC)А вообще у меня не поток байт, а подписанное сообщение. И в нем - сертификат, в котором естественно все написано по-русски. И надо информацию о подписи выводить.
(no subject)
From:no subject
Date: 2009-09-16 10:56 pm (UTC)А вообще грустно все это, да.
no subject
Date: 2009-09-16 11:14 pm (UTC)И потом уже дёргать за копию. Я не знаю, почему это опасно (Гвидо не стал бы зря прятать полезную функцию), но, если вызвать её достаточно рано, то ничего вроде не ломается. По крайней мере, в своих написанных на Питоне приладах для Вима я этим пользуюсь. Правда, под Вин32, под нормальной системой ещё не успел проверить.
P.S. setappdefaultencoding -- имя произвольное, но так было в том месте, где я прочитал эту идею, и мне оно понравилось.
... Имя Бо Яна известно всем китайцам ...
no subject
Date: 2009-09-16 11:21 pm (UTC)... А если сломается время - мы его тоже починим? ...
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2009-09-17 05:45 am (UTC)Ну у людей бывают странные заскоки. Вон в openvpn и encfs почему-то имеется совершенно необъяснимая нелюбовь к режимам шифрования, отличным от CBC. Никто в openvon-devel объяснить не мог. Мы с Игусом голову сломали, да так и не поняли чем им
CTR и CFB не нравятся.
no subject
Date: 2009-09-17 03:08 am (UTC)no subject
Date: 2009-09-17 05:42 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2009-09-17 06:26 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2009-09-17 06:53 am (UTC)На самом деле, ни на чём не основанное суждение. Проекты бывают разные.
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2009-09-17 09:28 am (UTC)(no subject)
From:(no subject)
From:no subject
Date: 2009-09-18 10:44 am (UTC)В моем понимании данного термина серьёзные проекты на питоне таки вполне пишутся и не сказать, чтобы приходилось с питоном для этого серьёзно воевать.
Не могу не процитировать :)
Date: 2009-09-18 11:09 am (UTC)Re: Не могу не процитировать :)
From:Re: Не могу не процитировать :)
From:Re: Не могу не процитировать :)
From:no subject
Date: 2009-09-17 05:14 am (UTC)Вопрос, разумеется, в кодеках, которые имеют к локали весьма опосредованное отношение. Дефолтный кодек в питоне - 'ascii', он не пропускает юникода.
Наиболее дешёвым вариантом вывода юникода куда угодно является насильное преобразование из типа юникод в тип стринг следующего вида:
u'Привет, мерзавцы'.encode('utf-8').
А вот за что убить голландца таки надо - так это за отдельный тип unicode :)
no subject
Date: 2009-09-17 05:47 am (UTC)А Ларри Уолла так по-моему и не допинали, хотя он с 5.6 начиная облизывается на работу с unicode, а на дворе уже 5.10.
Про японцев, которые Руби делают, я уж вообще молчу. Те б и сами догадаться могли.
(no subject)
From:(no subject)
From:no subject
Date: 2009-09-17 09:31 am (UTC)(no subject)
From:no subject
Date: 2009-09-17 06:31 am (UTC)нефиг пытаться писать unicode в ascii файл.
надо делать так:
buriy@bur-mac:~$ python > 123 Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> print u"Привет" Traceback (most recent call last): File "", line 1, in UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128) >>> print u"Привет".encode('utf-8') # or >>> print u"Привет".encode('utf-16') #Unicode16-LEи всё ок!no subject
Date: 2009-09-17 06:34 am (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2009-09-17 06:32 am (UTC)import sys; reload(sys); sys.setdefaultencoding(encoding)
Рецепт тут: http://lxj.endofinternet.net/blog/2009/02/encodings-in-python/
no subject
Date: 2009-09-17 09:25 am (UTC)2. locale.getdefaultlocale(), locale.getpreferredencoding() и sys.getdefaultencoding() можно вызвать, не вызывая setlocale().
3. sys.setdefaultencoding() делать нельзя. Я когда-то делал, и получал многочисленные советы перестать - нарвёшься на проблемы. Я нарвался на проблемы, перестал, и теперь присоединяюсь к хору и другим советую перестать.
no subject
Date: 2009-09-17 02:20 pm (UTC)... Не рой другому яму сам! ...
(no subject)
From:no subject
Date: 2009-09-17 01:16 pm (UTC)Многие мои программы начинаются так:
где Locale.py:
import sys, locale, os def force_utf8_hack(): reload(sys) sys.setdefaultencoding('utf-8') for attr in dir(locale): if attr[0:3] != 'LC_': continue aref = getattr(locale, attr) locale.setlocale(aref, '') (lang, enc) = locale.getlocale(aref) if lang != None: try: locale.setlocale(aref, (lang, 'UTF-8')) except: os.environ[attr] = lang + '.UTF-8'no subject
Date: 2009-09-18 07:36 am (UTC)import locale
ENCODING = locale.getpreferredencoding()
...
print u"ляляля".encode(ENCODING)
Обычно оказывается ENCODING=='utf-8', но мало ли чего...