Sys.stdin.read: примеры (PYTHON)
sys.stdin.read(size: int): strОписание функции sys.stdin.read
Функция sys.stdin.read() является методом объекта файла, представляющего стандартный поток ввода (stdin) в Python. Она предназначена для чтения данных из этого потока до достижения конца файла (EOF).
Функция используется в случаях, когда программа должна получить данные из внешнего источника, например, через конвейер (pipe) в командной строке, перенаправление файла или ручной ввод, завершаемый сигналом EOF (Ctrl+D в Linux/Mac, Ctrl+Z+Enter в Windows).
Аргументы функции:
size(опциональный): целое число, определяющее максимальное количество символов (в текстовом режиме) или байт (в бинарном режиме) для чтения. Если аргумент не указан или имеет отрицательное значение, функция читает весь ввод до EOF.
Возвращаемое значение:
- Строка (
str) при чтении из stdin в текстовом режиме. - Байтовый объект (
bytes) при чтении из stdin, открытого в бинарном режиме (например,sys.stdin.buffer.read()). - Пустая строка (
'') или байтовый объект (b'') при достижении конца потока без введенных данных.
Простые примеры использования
Пример 1: Чтение всего ввода до EOF.
import sys
data = sys.stdin.read()
print(f"Получено {len(data)} символов.")
# Ввод: Hello\nWorld\nCtrl+D
# Вывод: Получено 12 символов (включая символы новой строки).Получено 12 символов.
Пример 2: Чтение ограниченного числа символов.
import sys
# Чтение только первых 5 символов.
partial_data = sys.stdin.read(5)
print(f"Прочитано: '{partial_data}'")
# Ввод: Hello World\nCtrl+D
# Вывод: Прочитано: 'Hello'Прочитано: 'Hello'
Пример 3: Чтение в бинарном режиме.
import sys
# Чтение байтов из стандартного ввода.
byte_data = sys.stdin.buffer.read(4)
print(f"Байты: {byte_data}")
# Ввод: abcd\n (вводится как текст, но читается как байты)
# Вывод: Байты: b'abcd'Байты: b'abcd'
Похожие функции в Python
sys.stdin.readline(): Читает одну строку из ввода, включая символ новой строки \n. Эффективна для построчного чтения больших объемов данных. Функция readline() возвращает пустую строку при достижении EOF.
import sys
line = sys.stdin.readline()
print(f"Строка: {line}")input(): Встроенная функция, читающая строку из стандартного ввода без завершающего символа новой строки. Функция input() также выводит необязательное приглашение. Она вызывает исключение EOFError при обнаружении конца файла.
user_input = input("Введите текст: ")
print(f"Вы ввели: {user_input}")sys.stdin.readlines(): Читает все строки из ввода и возвращает их список. Функция может принимать параметр hint для ограничения общего количества читаемых символов.
import sys
lines = sys.stdin.readlines()
print(f"Прочитано {len(lines)} строк.")fileinput.input(): Функция модуля fileinput, которая позволяет прозрачно читать данные как из файлов, переданных в аргументах командной строки, так и из стандартного ввода.
import fileinput
for line in fileinput.input():
print(line.strip())Когда что использовать: Функцию sys.stdin.read() применяют для чтения всего ввода как единого блока, например, при обработке данных JSON, XML или большого текста. Функции readline() и input() удобны для интерактивного диалога или построчной обработки логов. Функция fileinput.input() подходит для создания утилит командной строки, работающих и с файлами, и с stdin.
Аналоги в других языках программирования
PHP: Используют поток php://stdin и функцию file_get_contents() или построчное чтение с fgets(STDIN).
<?php
$allInput = file_get_contents('php://stdin');
echo "Прочитано: " . strlen($allInput) . " байт\n";
?>// Запуск: echo 'test' | php script.php // Вывод: Прочитано: 5 байт
JavaScript (Node.js): Используют модуль process и событийный поток process.stdin.
process.stdin.on('data', chunk => {
console.log(`Получено: ${chunk.length} байт`);
});
process.stdin.on('end', () => {
console.log('Ввод завершен.');
});// Запуск: echo 'data' | node script.js // Вывод: Получено: 5 байт\nВвод завершен.
Java: Используют System.in, который является InputStream. Часто оборачивают его в BufferedReader или Scanner.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String data = scanner.useDelimiter("\\A").next();
System.out.println("Длина: " + data.length());
}
}// Запуск: echo 'text' | java Main // Вывод: Длина: 5
C#: Используют Console.OpenStandardInput() или Console.In для текстового чтения.
using System;
class Program {
static void Main() {
string input = Console.In.ReadToEnd();
Console.WriteLine($"Символов: {input.Length}");
}
}// Запуск: echo 'text' | dotnet run // Вывод: Символов: 5
Golang: Используют пакет os и функцию ioutil.ReadAll (или io.ReadAll в новых версиях).
package main
import (
"fmt"
"io"
"os"
)
func main() {
data, _ := io.ReadAll(os.Stdin)
fmt.Printf("Байт: %d\n", len(data))
}// Запуск: echo 'text' | go run script.go // Вывод: Байт: 5
Отличия: В отличие от Python, где sys.stdin.read() возвращает строку, во многих языках (Java, C#, Go) чтение по умолчанию работает с байтами, и требуется явное преобразование. В Node.js используется асинхронная, событийная модель. В PHP для доступа к stdin используют специальный URL-поток.
Типичные ошибки
1. Блокировка выполнения: Функция sys.stdin.read() без аргументов будет ждать ввода до EOF. В интерактивном режиме это может выглядеть как "зависание" программы, если пользователь не знает, как передать EOF.
# Ожидание EOF, которое никогда не наступит в интерактивном режиме без правильной команды.
import sys
print("Введите текст (Ctrl+D для завершения):")
data = sys.stdin.read() # Программа "зависнет" здесь, ожидая EOF.
print("Готово.")2. Проблемы с кодировкой: При чтении не-текстовых данных или данных в другой кодировке в текстовом режиме может возникнуть ошибка UnicodeDecodeError.
import sys
# Попытка прочитать бинарные данные как текст.
# Эмуляция: echo -e '\\x80' | python script.py
# Возможная ошибка: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80...3. Чтение после EOF: Повторный вызов read() после достижения конца потока вернет пустую строку, что иногда не ожидается логикой программы.
import sys
data1 = sys.stdin.read(5) # Прочитает первые 5 символов.
data2 = sys.stdin.read() # Прочитает все остальное до EOF.
# Если ввод был короче 5 символов, data2 будет пустой строкой.4. Смешивание методов чтения: Одновременное использование input() и sys.stdin.read() в одной программе может привести к непредсказуемому поведению, так как input() может читать часть данных, оставляя остаток для read().
import sys
name = input("Имя: ") # Пользователь вводит 'Анна' и нажимает Enter.
# В stdin остался символ новой строки '\n'.
rest = sys.stdin.read() # Этот вызов немедленно получит оставшийся '\n' (если он есть) и будет ждать EOF.
print(f"Имя: {name}, Остаток: '{rest}'")Изменения в последних версиях Python
Функция sys.stdin.read() не претерпела значительных синтаксических изменений в последних основных версиях Python (3.x). Однако её поведение зависит от объекта sys.stdin, который по умолчанию является буферизированным потоком в текстовом режиме.
Важные аспекты, связанные с версиями:
- В Python 3 объекты стандартных потоков (
sys.stdin,sys.stdout,sys.stderr) по умолчанию используют кодировку UTF-8 и режим обработки ошибокstrictдля текста. Это можно изменить через переменные окружения (например,PYTHONIOENCODING). - Добавлен атрибут
sys.stdin.bufferдля доступа к бинарному потоку ввода, что позволяет более гибко управлять чтением данных. Функцияsys.stdin.buffer.read()является бинарным аналогом. - Версии Python, начиная с 3.7, улучшили поддержку асинхронного ввода-вывода через модуль
asyncio, но для непосредственной работы соsys.stdinв асинхронном контексте требуются специальные обертки (например,asyncio.to_threadв Python 3.9+).
Таким образом, сам метод read() остается стабильным, но контекст его использования (кодировки, буферизация, асинхронность) развивается вместе с языком.
Расширенные и специальные примеры
Пример 1: Обработка большого JSON из stdin. Функция read() удобна для чтения всего JSON-документа, который может быть передан через конвейер.
import sys, json
raw_data = sys.stdin.read()
try:
data = json.loads(raw_data)
print(f"Успешно загружено. Ключи: {list(data.keys())}")
except json.JSONDecodeError as e:
print(f"Ошибка JSON: {e}")# Запуск: echo '{"name": "John", "age": 30}' | python script.py
# Вывод: Успешно загружено. Ключи: ['name', 'age']Пример 2: Фильтрация данных на лету. Чтение всего ввода, обработка и вывод результата.
import sys
text = sys.stdin.read()
# Замена всех цифр на символ 'X'
filtered_text = ''.join(['X' if c.isdigit() else c for c in text])
sys.stdout.write(filtered_text)# Запуск: echo 'Phone: 123-45-67' | python script.py # Вывод: Phone: XXX-XX-XX
Пример 3: Использование с аргументом size и обработка в цикле для контроля памяти при потенциально большом вводе.
import sys
CHUNK_SIZE = 1024 # 1 КБ
while True:
chunk = sys.stdin.read(CHUNK_SIZE)
if not chunk: # Пустая строка означает EOF
break
# Обработка чанка (например, подсчет символов)
print(f"Получен чанк длиной {len(chunk)}.", end=' ')
print(f"Последний символ: {repr(chunk[-1]) if chunk else 'нет'}")# Запуск: head -c 5000 /dev/urandom | python script.py # Пример вывода: # Получен чанк длиной 1024. Последний символ: 'z' # Получен чанк длиной 1024. Последний символ: 'A' # ...
Пример 4: Чтение из stdin, если он не пуст, иначе использование значения по умолчанию. Используется select для проверки доступности данных (работает на Unix-подобных системах).
import sys
import select
# Ждем доступности данных в stdin не более 0.5 секунды.
if select.select([sys.stdin], [], [], 0.5)[0]:
data = sys.stdin.read()
else:
data = "Данные по умолчанию\n"
print(f"Используемые данные:\n{data}")# Запуск 1: python script.py (без ввода, подождать 0.5 сек) # Вывод: Используемые данные:\nДанные по умолчанию # Запуск 2: echo "Привет" | python script.py # Вывод: Используемые данные:\nПривет
Пример 5: Комбинирование sys.stdin.read() с другими потоками. Чтение из stdin и запись в stderr для логирования.
import sys
sys.stderr.write("Начинаем чтение...\n")
data = sys.stdin.read()
sys.stderr.write(f"Прочитано {len(data)} символов.\n")
# Основной вывод в stdout.
print(f"ОБРАБОТКА: {data.upper()}")# Запуск: echo 'test' | python script.py 2> log.txt # Содержимое log.txt: Начинаем чтение...\nПрочитано 5 символов. # Вывод на экран (stdout): ОБРАБОТКА: TEST