Как уже говорили другие, # coding:
указывает кодировку, в которой сохранен исходный файл. Вот несколько примеров, иллюстрирующих это:
Файл сохранен на диске как cp437 (моя кодировка консоли), но кодировка не объявлена
b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)
Выход:
File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details
Вывод файла с добавлением # coding: cp437
:
über '\x81ber'
über u'\xfcber'
Сначала Python не знал кодировку и жаловался на не-ASCII символ. Как только он узнал кодировку, строка байтов получила байты, которые были на самом деле на диске. Для строки Unicode Python прочитал \ x81, знал, что в cp437 это было ü , и декодировал его в кодовую точку Unicode для ü , которая равна U + 00FC. Когда строка байта была напечатана, Python отправил шестнадцатеричное значение 81
непосредственно на консоль. Когда была напечатана строка Unicode, Python правильно определил кодировку моей консоли как cp437 и перевел Unicode ü в значение cp437 для ü .
Вот что происходит с файлом, объявленным и сохраненным в UTF-8:
├╝ber '\xc3\xbcber'
über u'\xfcber'
В UTF-8 ü кодируется как шестнадцатеричные байты C3 BC
, поэтому строка байтов содержит эти байты, но строка Unicode идентична первому примеру. Python прочитал два байта и правильно его расшифровал. Python неправильно напечатал строку байтов, потому что он отправил два байта UTF-8, представляющих ü , непосредственно на мою консоль cp437.
Здесь файл объявлен cp437, но сохранен в UTF-8:
├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'
Строка байтов все еще получает байты на диске (шестнадцатеричные байты UTF-8 C3 BC
), но интерпретирует их как два символа cp437 вместо одного символа в кодировке UTF-8. Те два символа, которые переведены в код Unicode, указывают, что все печатается неправильно.