Быстрый в изучении - мощный в программировании
>> Telegram ЧАТ для Python Программистов

Свободное общение и помощь советом и решением проблем с кодом! Заходите в наш TELEGRAM ЧАТ!

>> Python Форум Помощи!

Мы создали форум где отвечаем на все вопросы связанные с языком программирования Python. Ждем вас там!

>> Python Канал в Telegram

Обучающие статьи, видео и новости из мира Python. Подпишитесь на наш TELEGRAM КАНАЛ!

Проблемы с кодировкой в Python

В python есть 2 объекта работающими с текстом: unicode и str, объект unicode хранит символы в формате (кодировке) unicode, объект str является набором байт/символов в которых python хранит остальные кодировки (utf8, cp1251, cp866, koi8-r и др).

Кодировку unicode можно считать рабочей кодировкой питона т.к. она предназначена для её использования в самом скрипте - для разных операций над строками.

Внешняя кодировка (объект str) предназначена для хранения и передачи текстовой информации вне скрипта, например для сохранения в файл или передачи по сети. Поэтому в данной статье я её назвал внешней. Самой используемой кодировкой в мире является utf8 и число приложений переходящих на эту кодировку растет каждый день, таким образом превращаясь в "стандарт".

Эта кодировка хороша тем что для хранения текста она занимает оптимальное кол-во памяти и с помощью её можно закодировать почти все языки мира ( в отличие от cp1251 и подобных однобайтовых кодировок). Поэтому рекомендуется везде использовать utf8, и при написании скриптов.

Использование

Скрипт питона, в самом начале скрипта указываем кодировку файла и сохраняем в ней файл

# coding: utf8

либо

# -*- coding: utf-8 -*-

для того что-бы интерпретатор python понял в какой кодировке файл

Строки в скрипте

Строки в скрипте хранятся байтами, от кавычки до кавычки:

print 'Привет'

= 6 байт при cp1251

= 12 байт при utf8

Если перед строкой добавить символ u, то при запуске скрипта, эта байтовая строка будет декодирована в unicode из кодировки указанной в начале:

# coding:utf8
print u'Привет'

и если кодировка содержимого в файле отличается от указанной, то в строке могут быть "битые символы"

Загрузка и сохранение файла

# coding: utf8
# Загружаем файл с кодировкай utf8
text = open('file.txt','r').read()
# Декодируем из utf8 в unicode - из внешней в рабочую
text = text.decode('utf8')
# Работаем с текстом
text += text
# Кодируем тест из unicode в utf8 - из рабочей во внешнюю
text = text.encode('utf8')
# Сохраняем в файл с кодировкий utf8
open('file.txt','w').write(text)

Текст в скрипте

# coding: utf8
a = 'Текст в utf8'
b = u'Текст в unicode'
# Эквивалентно: b = 'Текст в unicode'.decode('utf8')
# т.к. сам скрипт хранится в utf8
print 'a =',type(a),a
# декодируем из utf-8 в unicode и далее unicode в cp866 (кодировка консоли winXP ru)
print 'a2 =',type(a),a.decode('utf8').encode('cp866')
print 'b =',type(b),b

Процедуре print текст желательно передавать в рабочей кодировке либо кодировать в кодировку ОС.

Результат скрипта при запуске из консоли windows XP:

a = ╨в╨╡╨║╤Б╤В ╨▓ utf8

a2 = Текст в utf8

b = Текст в unicode

В последней строке print преобразовал unicode в cp866 автоматический, см. следующий пункт

Авто-преобразование кодировки

В некоторых случаях для упрощения разработки python делает преобразование кодировки, пример с методом print можно посмотреть в предыдущем пункте.

В примере ниже, python сам переводит utf8 в unicode - приводит к одной кодировке для того что-бы сложить строки.

# coding: utf8
# Устанавливаем стандартную внешнюю кодировку = utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
a = 'Текст в utf8'
b = u'Текст в unicode'
c = a + b
print 'a =',type(a),a
print 'b =',type(b),b
print 'c =',type(c),c

Результат

a = Текст в utf8

b = Текст в unicode

c = Текст в utf8Текст в unicode

Как видим результирующая строка "c" в unicode. Если бы кодировки строк совпадали то авто-перекодирования не произошло бы и результирующая строка содержала кодировку слагаемых строк.

Авто-перекодирование обычно срабатывает когда происходит взаимодействие разных кодировок.

Пример авто-преобразования кодировок в сравнении

# coding: utf8
# Устанавливаем стандартную внешнюю кодировку = utf8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
print '1. utf8 and unicode', 'true' if u'Слово'.encode('utf8') == u'Слово' else 'false'
print '2. utf8 and cp1251', 'true' if u'Слово'.encode('utf8') == u'Слово'.encode('cp1251') else 'false'
print '3. cp1251 and unicode', 'true' if u'Слово'.encode('cp1251') == u'Слово' else 'false'

Результат

1. utf8 and unicode true

2. utf8 and cp1251 false

script.py:10: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal

print '3. cp1251 and unicode', 'true' if u'Слово'.encode('cp1251') == u'Слово' else 'false'

3. cp1251 and unicode false

В сравнении 1, кодировка utf8 преобразовалась в unicode и сравнение произошло корректно.

В сравнении 2, сравниваются кодировки одного вида - обе внешние, т.к. кодированы они в разных кодировках условие выдало что они не равны.

В сравнении 3, выпало предупреждение из за того что выполняется сравнение кодировок разного вида - рабочая и внешняя, а авто-декодирование не произошло т.к. стандартная внешняя кодировка = utf8, и декодировать строку в кодировке cp1251 методом utf8 питон не смог.

Вывод списков

# coding: utf8
d = ['Тест','списка']
print '1',d
print '2',d.__repr__()
print '3',','.join(d)

Результат:

1 ['\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', '\xd1\x81\xd0\xbf\xd0\xb8\xd1\x81\xd0\xba\xd0\xb0']

2 ['\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', '\xd1\x81\xd0\xbf\xd0\xb8\xd1\x81\xd0\xba\xd0\xb0']

3 Тест,списка

При выводе списка, происходит вызов [{repr}]() который возвращает внутреннее представление этого спиcка - print 1 и 2 являются аналогичными. Для корректного вывода списка, его нужно преобразовать в строку - print 3.

Установка внешней кодировки при запуске

PYTHONIOENCODING=utf8 python 1.py

В обучении ребенка важно правильное толкование окружающего его мира. Существует масса полезных журналов которые начнут экологическое воспитание дошкольников правильным путем. Развивать интерес к окружающему миру очень трудный но интересный процесс, уделите этому особое внимание.

Комментариев: 4
  1. как преобразовать программный код Python в исполняемый файл

  2. сам понял , как это делают

  3. Alex, если Вы сами нашли решение, то можете им поделиться. Пользователи которые ищут решение проблемы будут Вам благодарны.

    А так, в Linux можно в свойствах файла поставить галочку на "Свойства > Права > Выполнение:разрешить выполнение файла как программу".

  4. Мармеладный Джордж | 2016-09-04 в 14:48:19

    Archy, подозреваю имелась ввиду компилияция файлов, возможно с помощью cxPython, py2exe