Помогите новичку разобраться (Python 3.4)
Есть такой файл в кодировке utf-8(без BOM) text-data.txt, содержит одну строку:
Привет Мир!
я пытаюсь читать его в текстовом режиме в консоли:
open(r'D:\python\text-data.txt').read()
Получаю: 'Привет РњРёСЂ!'
Если открываю тот же файл в двоичном режиме с последующей декодировкой:
open(r'D:\python\text-data.txt', 'rb').read().decode()
Получаю своё: 'Привет Мир!'
При этом, помнится, у М. Лутца (Изучаем Python 4 изд. стр. 1021 последний абзац) написано:
“Содержимое файлов, открытых в текстовом режиме, интерпретируется
как текст, состоящий из символов Юникода. При этом используется либо
кодировка по умолчанию в соответствии с настройками системы, либо
кодировка, которая была указана явно…”
Так вот я смотрю что системная кодировка у меня:
sys.getdefaultencoding() # utf-8
Вопрос почему при открытии файла в текстовом режиме и кодировке по умолчанию
utf-8 я получаю кракозябры? Оно что таки не работает в случае с файлами?
Просто в более сложном сценарии который имитирует утилиту “more” если попытаться этим сценарием прочитать самого себя:
>>>D:\python\programming1>more.py more.py
то русский текст (в комментах) так вообще вызывает ошибку:
def more(text, num_lines=15): lines = text.splitlines() # подобно split('\n') но без '' в конце while lines: chunk = lines[:num_lines] # от 0 до 15 линии lines = lines[num_lines:] # от 15 линии до конца for line in chunk: # печатаем линии от 0 до 15 print(line) if lines and input('More?') not in ['y', 'Y']: # Если еще остались линии на ззапрос 'More?' break # ответили иначе чем 'y' или 'Y' то на выход if __name__ == '__main__': import sys # если запускается как сценарий more(open(sys.argv[1]).read(), 10) # отобразить постранично содержимое # файла, указанного в командной строке
- Этот сценарий вылетает с ошибкой:
UnicodeEncodeError: ‘charmap’ codec can't encode character ‘\u0455’ in position 61: character maps to <undefined>
Но вот если убрать комменты на русском, или если делать так:
def more(text, num_lines=15): lines = text.splitlines() # подобно split('\n') но без '' в конце while lines: chunk = lines[:num_lines] # от 0 до 15 линии lines = lines[num_lines:] # от 15 линии до конца for line in chunk: # печатаем линии от 0 до 15 print(line.decode('utf-8')) if lines and input('More?') not in ['y', 'Y']: # Если еще остались линии на ззапрос 'More?' break # ответили иначе чем 'y' или 'Y' то на выход if __name__ == '__main__': import sys # если запускается как сценарий more(open(sys.argv[1], 'rb').read(), 10) # отобразить постранично содержимое # файла, указанного в командной строке
То все ок. Может кто-нибудь объяснить почему так происходит?