Как считывать строки в Python: от input до readline

Раздел: Ввод-вывод -> Чтение строк

Чтение строк с помощью readline в Python

Как эффективно прочитать одну строку из стандартного ввода, сохраняя символ перевода строки?

Основной способ чтения строки в Python, соответствующий низкоуровневой работе с потоками, - использование метода readline объекта sys.stdin. Этот метод возвращает строку вместе с завершающим символом новой строки (\n), если он присутствует. Такой подход особенно полезен при пакетной обработке входных данных, когда каждая строка должна быть проанализирована с учётом её границы.

import sys
line = sys.stdin.readline()
print(repr(line))

Python input readline (чтение строки через readline)

Вывод при вводе Hello и нажатии Enter:

'Hello\n'

чтение строки python (чтение строки в python)

Если нужно удалить символ перевода строки, применяется метод rstrip():

line = sys.stdin.readline().rstrip('\n')
print(repr(line))
'Hello'

Такой вариант гарантирует, что при чтении пустой строки (просто Enter) будет получена пустая строка, а не строка с одним символом новой строки.

Как прочитать строку без символа перевода строки, используя input?

Функция input() автоматически удаляет завершающий символ новой строки и возвращает чистую строку. Это самый распространённый метод в интерактивных программах. Отличие от readline в том, что input() не сохраняет \n, но добавляет возможность вывода приглашения (prompt).

name = input('Введите имя: ')
print(f'Привет, {name}!')

Для чтения строк без приглашения используется:

data = input()

Основной случай использования - диалоговые скрипты, где пользователю нужно указать только одно значение. input() удобнее, так как не требует импорта модуля sys.

Как использовать модуль readline для истории ввода и автодополнения?

Модуль readline в Python не предназначен для прямого чтения строк, а служит для улучшения интерактивного ввода: добавляет историю команд, возможность перемещения по истории стрелками, автодополнение по Tab. Он автоматически подключается к input() и sys.stdin.readline() в интерактивном режиме, если установлен (на Unix-системах).

Чтобы убедиться, что модуль загружен, можно импортировать его:

import readline
# Теперь history и автодополнение доступны для input() и sys.stdin.readline()

Настройка автодополнения выполняется через readline.set_completer() и readline.parse_and_bind(). Пример:

import readline

def complete(text, state):
    options = ['apple', 'apricot', 'banana', 'cherry']
    matches = [opt for opt in options if opt.startswith(text)]
    if state < len(matches):
        return matches[state]
    return None

readline.set_completer(complete)
readline.parse_and_bind('tab: complete')

fruit = input('Введите фрукт: ')
print(f'Вы выбрали {fruit}')

После запуска при нажатии Tab будет предложено автодополнение. Это полезно для создания интерактивных интерпретаторов и консольных утилит с предсказуемым вводом.

Как обработать несколько строк в цикле с помощью readline?

При чтении большого количества строк из стандартного ввода (например, через конвейер) эффективно использовать цикл с sys.stdin.readline(). При этом завершение ввода обрабатывается как возврат пустой строки (сигнал EOF).

import sys
while True:
    line = sys.stdin.readline()
    if not line:
        break
    print(f'Прочитано: {line.rstrip()}\r')

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

Ввод:
строка1
строка2
^D (Ctrl+D)
Вывод:
Прочитано: строка1
Прочитано: строка2

Этот вариант подходит для фильтрации или трансформации потока данных в реальном времени.

Какие типичные ошибки возникают при работе с readline и как их исправить?

  • Ошибка: забыли удалить символ новой строки. Если не выполнить rstrip(), строка будет содержать \n, что может нарушить сравнение или вывод. Решение: всегда обрабатывать строку после чтения.
  • Ошибка: использование input() и sys.stdin.readline() вперемешку. input() считывает строку, но может оставить необработанный символ \n в буфере, если его неправильно скомбинировать. Лучше придерживаться одного метода.
  • Ошибка: неправильная обработка EOF. Если ввод заканчивается, sys.stdin.readline() возвращает пустую строку, а input() выбрасывает исключение EOFError. Для input() нужно обернуть вызов в try-except.
  • Ошибка: модуль readline не работает на Windows. На Windows модуль readline может отсутствовать. Альтернатива - использовать pyreadline (установить через pip) или prompt_toolkit.
  • Ошибка: потеря производительности при чтении больших файлов. Для чтения из файла лучше использовать open() и его собственный readline(), а не перенаправлять stdin. Если требуется читать из stdin по строкам, цикл с readline() - оптимальное решение.

Расширенные примеры использования readline

Пример 1: Чтение строк из файла с помощью readline и обработка пустых строк

Пример
with open('data.txt', 'r') as f:
    line = f.readline()
    while line:
        # Удаляем лишние пробелы, но не символ новой строки, если нужен
        clean = line.rstrip('\n')
        if clean:
            print(f'Строка: {clean}')
        line = f.readline()

Результат для файла с содержимым:

Первая строка

Третья строка
Вывод:
Строка: Первая строка
Строка: Третья строка

Пояснение: метод readline() файлового объекта возвращает строку вместе с символом новой строки. Пустая строка (просто \n) превращается в ''? Нет, при пустой строке возвращается '\n', поэтому условие if clean: пропускает пустые строки. Этот приём полезен при фильтрации CSV или логов.

Пример 2: Использование модуля readline для сохранения истории ввода

Пример
import readline
import sys

# Включаем историю ввода
readline.read_history_file('history.txt')  # загрузка предыдущей истории
print('Введите строки. Для выхода - пустая строка.')
while True:
    line = input('> ')
    if line == '':
        break
    print(f'Запись: {line}')
readline.write_history_file('history.txt')

Результат: после запуска можно перемещаться по предыдущим вводам стрелками вверх/вниз. История сохраняется между запусками.

Пояснение: read_history_file и write_history_file позволяют сохранять ввод пользователя. Это удобно для REPL-приложений и оболочки команд.

Пример 3: Комбинация sys.stdin.readline и генератора для ленивого чтения

Пример
import sys

def read_lines():
    while True:
        line = sys.stdin.readline()
        if not line:
            break
        yield line.rstrip('\n')

for i, line in enumerate(read_lines(), 1):
    print(f'{i}: {line}')

Результат: нумерует строки, читаемые из stdin, без загрузки всего ввода в память.

Ввод:
один
два
три
^D
Вывод:
1: один
2: два
3: три

Пояснение: генератор read_lines возвращает строки по одной. Этот паттерн часто применяется при обработке больших файлов или сетевых потоков.

Пример 4: Считывание многострочного ввода с помощью sys.stdin.readline до маркера конца

Пример
import sys

print('Введите текст. Для завершения введите END:')
lines = []
while True:
    line = sys.stdin.readline()
    if line.rstrip('\n') == 'END':
        break
    lines.append(line.rstrip('\n'))
print('Введённые строки:')
for l in lines:
    print(l)

Результат:

Введите текст. Для завершения введите END:
строка1
строка2
END
Введённые строки:
строка1
строка2

Пояснение: маркер конца строки (END) позволяет пользователю завершить ввод без сигнала EOF. Это полезно в интерактивных редакторах или при вводе структурированных данных.

Пример 5: Использование io.StringIO для тестирования кода, читающего через readline

Пример
import sys
import io

test_input = 'строка A\nстрока B\n'
sys.stdin = io.StringIO(test_input)

line1 = sys.stdin.readline()
line2 = sys.stdin.readline()
print(repr(line1))
print(repr(line2))

# Восстанавливаем stdin
sys.stdin = sys.__stdin__

Результат:

'строка A\n'
'строка B\n'

Пояснение: подмена sys.stdin на io.StringIO позволяет эмулировать ввод для модульного тестирования. После завершения следует восстановить оригинальный stdin.

Пример 6: Обработка строк с кодировкой через readline (например, чтение из сокета)

Пример
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('example.com', 80))
sock.sendall(b'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
response = b''
while True:
    chunk = sock.recv(1024)
    if not chunk:
        break
    response += chunk
# Первая строка ответа
header_line = response.split(b'\r\n')[0]
print(header_line.decode('utf-8'))
sock.close()

Результат: например, HTTP/1.1 200 OK.

Пояснение: в сетевом программировании readline обычно не применяется напрямую; используется ручное разделение по разделителю. Однако принцип считывания до символа новой строки сохраняется. Для больших объёмов данных следует использовать буферизированное чтение.

Чтение строки через readline - comments

En
Python input readline (python)