Форум сайта python.su
0
Ситуация такая:
C:\> type a.py
# -*- coding: cp866 -*-
import sys
a = "п"
b = sys.argv[1]
print ord(a), a
print ord(b), b
C:\> a.py п
175 п
239 я
C:\> chcp
Текущая кодовая страница: 866
Офлайн
32
лучше кодить в utf-8,
# -*- coding: utf-8 -*-
b = sys.argv[1].decode('cp866')
#b = sys.argv[1].decode('cp1251')
Офлайн
0
Так уже пробовал, к сожалению не работает, можно перекодировать так b = unicode(sys.argv, “cp1251”).encode(“cp866”) но ето не подходит поскольку если на вход мы дадим чтото вроде “▓” то после пере кодировки получим “-”, потому-что таких символов в cp1251 просто нет.
# -*- coding: utf-8 -*-
import sys
b = sys.argv[1].decode('cp866')
print ord(b), b
лучше кодить в utf-8лучше, вам, мне, но не тому для кого я кодю.
Офлайн
14
У вас же винда? Можно просто в лоб: GetCommandLineW/CommandLineToArgvW. Потребуется еще LocalFree. Завернуть все через ctypes - и будут юникодные command line arguments. А дальше уже не важно, cp866 вам нужна или 1251.
Офлайн
0
Андрей Светловспасибо, кое как получается но это тоже не вариант, WinAPI для такой цели это уже перебор. Нужно выяснить почему sys.argv снимает аргументы в кодировке 1251. Наверное потому-что locale.getpreferredencoding() возвращает cp1251, а то-есть кодировку для текстовых данных
У вас же винда? Можно просто в лоб: GetCommandLineW/CommandLineToArgvW. Потребуется еще LocalFree. Завернуть все через ctypes - и будут юникодные command line arguments. А дальше уже не важно, cp866 вам нужна или 1251.
Return the encoding used for text data, according to user preferences.и как ее бы изменить?
Офлайн
32
gmanясен перец, мы ж в уникод перевели, из него можно в любой другой переводить
получаю: 1097 щ
# -*- coding: cp866 -*-
import sys
a = "п"
b = sys.argv[1].decode('cp1251').encode('cp866')
print ord(a), a
print ord(b), b
Офлайн
14
Изменить кодировку можно.
Она ставится в site.py самом конце как sys.setdefaultencoding
Можно положить куда-нибудь в путь, который попадает в sys.path (рядом с самим скриптом, например) sitecustomize.py.
И вызвать в нем sys.setdefaultencoding - но это будет означать, что для вашего скрипта кодировка изменится глобально.
Вам именно это нужно?
Офлайн
0
to o7412369815963
я уже писал почему перекодирование не подходит.
Андрей Светловда, а почему нельзя вызывать sys.setdefaultencoding() внутри скрипта? Вот вроде отрабатывает, но изменений нет:
Изменить кодировку можно.
Она ставится в site.py самом конце как sys.setdefaultencoding
Можно положить куда-нибудь в путь, который попадает в sys.path (рядом с самим скриптом, например) sitecustomize.py.
И вызвать в нем sys.setdefaultencoding - но это будет означать, что для вашего скрипта кодировка изменится глобально.
Вам именно это нужно?
# -*- coding: cp866 -*-
import sys
reload(sys)
print "old:", sys.getdefaultencoding()
sys.setdefaultencoding("cp866")
print "new:", sys.getdefaultencoding()
a = "п"
b = sys.argv[1]
print ord(a), a
print ord(b), b
> a.py п
old: ascii
new: cp866
175 п
239 я
Офлайн
14
Извините, но я ошибся по поводу sitecustomize (не люблю его, ох как сильно - слишком много раз приходилось “выкусывать” sitecustomize из кода проектов).
Так вот, он вам не поможет.
Наконец-то посмотрел в исходники питона.
Что увидел: initmain вызывается перед initsite, который в свою очередь дергает sitecustomize. Это все - импорты, а не запуск модулей. Поэтому на момент окончания шабаша __main__ не видит setdefaultencoding. Трюк с перезагрузкой sys вообще бесполезен при правильном использовании.
А argv запоминается именно в initmain - и потом не меняется. Я просто раньше для сложных случаев строил свой “python.exe запускач” - и там рулил питоном как хотел - у него несколько шагов по запуску интерпретатора, в каждый можно влезть на уровне C API.
Запоминается, подчеркну, в C API ядре. И потом его снаружи поменять - никак.
Нет, все таки можно - поскольку sys.argv честный список:
for i in xrange(sys.argv):
sys.argv = sys.argv.encode('cp1251').decode('cp866')
Или вы делаете свою “запускачку” питона - где command line arguments будут поданы правильно - или таки юзаете windows api как я предлагал (второй вариант проще, ИМХО).
P.S. Когда я на PyCon взялся чинить баг с кодировками в import - на меня посмотрели странно. Т.е. - это конечно баг, и чинить его нужно. Только на наших маках и юниксах (ни у кого из разработчиков ядра не видел, для них мак - это ноутбук, а юникс/линукс - серверная платформа) - вашей беды не видать, все в utf-8. Хорошо у них :)
Отредактировано (Ноя. 19, 2009 01:21:20)
Офлайн
0
Андрей Светловя сам проблем с кодировками в python никогда не-знал, поскольку раньше писал исключительно под себя, исключительно под linux, и соответственно в utf-8. А тут взялся помочь человеку с курсачем, и стал прозревать с того какие они эти “проблемы с кодировками”, и как криво умеет работать виндовый терминал/какие у меня кривые руки (cp1251 он корректно отображает только со шрифтом Lucida Console). По этому важно не только рабочее решение, но и простое, которое студент сможет пошагово аргументировать(не зная python), ведь слова вроде: …а здесь мы с помощь модуля ctypes прибегнем к WinAPI для того чтоб снять аргумент запуска… или: …воспользуемся альтернативным ланчером python.exe для того чтоб обявить кодирову на єтапе initmain… это просто смешно.
P.S. Когда я на PyCon взялся чинить баг с кодировками в import - на меня посмотрели странно. Т.е. - это конечно баг, и чинить его нужно. Только на наших маках и юниксах (ни у кого из разработчиков ядра не видел, для них мак - это ноутбук, а юникс/линукс - серверная платформа) - вашей беды не видать, все в utf-8. Хорошо у них :)
Отредактировано (Ноя. 19, 2009 13:55:49)
Офлайн