Вопрос по python-3.x, encoding, python, stdin, unicode – Python 3: Как указать кодировку стандартного ввода [дубликата]

27

На этот вопрос уже есть ответ здесь:

Как изменить кодировку STDIN на Python 4 ответа

При переносе кода с Python 2 на Python 3 я сталкиваюсь с этой проблемой при чтении текста UTF-8 из стандартного ввода. В Python 2 это работает нормально:

for line in sys.stdin:
    ...

Но Python 3 ожидает ASCII отsys.stdin, и если на входе есть символы не ASCII, я получаю ошибку:

UnicodeDecodeError: 'ASCII» кодек можетt декодировать байт .. в позиции ..: порядковый номер не в диапазоне (128)

Для обычного файла я бы указал кодировку при открытии файла:

with open('filename', 'r', encoding='utf-8') as file:
    for line in file:
        ...

Но как я могу указать кодировку для стандартного ввода? Другие SO сообщения (например,Как изменить кодировку STDIN на Python) предложили использовать

input_stream = codecs.getreader('utf-8')(sys.stdin)
for line in input_stream:
    ...

Тем не менее, это неt работает в Python 3. Я все еще получаю то же сообщение об ошибке. Я'м, используя Ubuntu 12.04.2, и моя локаль установлена на en_US.UTF-8.

Ваш Ответ

1   ответ
54

не ожидать ASCII отsys.stdin, Это'откроюstdin в текстовом режиме и сделать обоснованное предположение о том, какая кодировка используется. Это предположение может сводиться кASCIIно это не дано. Увидетьsys.stdin документация о том, как выбран кодек.

Как и другие файловые объекты, открытые в текстовом режиме,sys.stdin объект происходит отio.TextIOBase базовый класс; оно имеет.buffer атрибут, указывающий на базовый буферизованный экземпляр IO (который в свою очередь имеет.raw атрибуты).

Обернутьsys.stdin.buffer приписать новыйio.TextIOWrapper() пример указать другую кодировку:

import io
import sys

input_stream = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')

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

Начиная с Python 3.7, вы также можетеперенастроить существующийstd* обертокпри условии, что вы делаете это в начале (до того, как какие-либо данные будут прочитаны):

# Python 3.7 and newer
sys.stdin.reconfigure(encoding='utf-8')
@CMCDragonkai: Python 3.7 добавляетwrite_through атрибути, что более важно, позволяет вамперенастроить оболочку Martijn Pieters
@IrshadBhat: Вы виделиОбернуть открытый поток с io.TextIOWrapper? Martijn Pieters
@MartijnPieters: это прекрасно работает! Спасибо! Весь сценарий:paste.pound-python.org/show/xoUPpsfFhtKssXBzLxBd  Удаление моих предыдущих неудач. bukzor
Если я используюio.TextIOWrapper(sys.stdin.buffer, encoding='utf-8') читать сstdin в питоне 2.7 это syasAttributeError: 'file' object has no attribute 'buffer', Как можно сделать чтение изstdin совместим с Python 2 и 3. Irshad Bhat

Похожие вопросы