Input() в Python 3: от простого ввода до продвинутых техник
Основы и варианты использования функции input() в Python 3
Функция input() в Python 3 читает строку, введённую пользователем, и возвращает её в виде строки. Эта функция является основным способом взаимодействия с пользователем через консоль. В отличие от Python 2, где существовали отдельно input() и raw_input(), в Python 3 input() всегда возвращает строку, а для получения чисел требуется явное преобразование.
Как получить от пользователя число и выполнить с ним арифметические действия?
Самый распространённый случай - ввод числа. Поскольку input() возвращает строку, её необходимо преобразовать в целое число (int()) или число с плавающей точкой (float()).
age_str = input("Введите ваш возраст: ") # ввод: 25
try:
age = int(age_str)
print("Через 10 лет вам будет", age + 10)
except ValueError:
print("Ошибка: необходимо ввести целое число.")Python 2 input (функция input() в python 2)
Введите ваш возраст: 25 Через 10 лет вам будет 35
Input python 3 (функция input() в python 3)
Типичные ошибки:
- Попытка сразу использовать строку в арифметике:
age + 10вызоветTypeError. - Если пользователь введёт буквы, преобразование
int()вызоветValueError. - Пустая строка также приведёт к
ValueError.
Как ввести несколько значений через пробел и обработать их?
Если требуется ввести несколько данных в одной строке, удобно использовать метод split() и, при необходимости, функцию map() для преобразования каждого элемента.
data = input("Введите три числа через пробел: ").split() # ввод: 10 20 30
if len(data) != 3:
print("Должно быть ровно три числа.")
else:
try:
a, b, c = map(int, data)
print("Сумма:", a + b + c)
except ValueError:
print("Ошибка: все значения должны быть целыми числами.")
Введите три числа через пробел: 10 20 30 Сумма: 60
Возможные проблемы: Неверное количество элементов, нечисловой ввод в одном из полей, лишние пробелы в начале/конце строки (метод split() их игнорирует).
Как защититься от некорректного ввода (ошибки преобразования)?
Для надёжности применяется конструкция try/except с циклом повторного запроса.
while True:
try:
n = int(input("Введите целое число: "))
break
except ValueError:
print("Пожалуйста, введите именно целое число. Попробуйте снова.")
print("Вы ввели:", n)
Введите целое число: abc Пожалуйста, введите именно целое число. Попробуйте снова. Введите целое число: 42 Вы ввели: 42
Распространённая ошибка: Зацикливание без сообщения пользователю - следует всегда информировать, что пошло не так.
Как выполнить введённое пользователем математическое выражение?
Использование eval(input()) позволяет вычислить любое выражение, но это очень опасно из-за возможности выполнения произвольного кода. Применяется только в контролируемой среде (например, собственные скрипты).
expr = input("Введите выражение (например, 2+2): ")
try:
result = eval(expr)
print("Результат:", result)
except Exception as e:
print("Ошибка вычисления:", e)
Введите выражение (например, 2+2): 3*4 Результат: 12
Предупреждение: eval() может выполнить любое выражение, включая удаление файлов. Никогда не используйте его с недоверенными данными.
Как ввести пароль, чтобы символы не отображались на экране?
Для скрытия ввода используется модуль getpass из стандартной библиотеки.
import getpass
password = getpass.getpass("Введите пароль: ")
print("Пароль принят.")
Введите пароль: Пароль принят.
Ограничение: Функция getpass.getpass() может не работать в некоторых средах (например, в IDLE). Кроме того, она не доступна в онлайн-интерпретаторах.
Как ввести несколько строк до пустой строки (многострочный ввод)?
Для сбора произвольного количества строк используется цикл с проверкой пустого ввода.
lines = []
while True:
line = input()
if line == "":
break
lines.append(line)
print("Введённые строки:")
for l in lines:
print(l)
Первая строка Вторая строка Введённые строки: Первая строка Вторая строка
Проблема: Если пользователь случайно нажмёт Enter, не введя ничего, сбор завершится. Для надёжности можно задать специальное стоп-слово.
Расширенные примеры работы с input()
1. Чтение чисел с дробной частью и обработка ошибок
Пример, где требуется ввод числа с плавающей точкой, а целое число также разрешено.
def get_float(prompt):
while True:
try:
val = float(input(prompt))
return val
except ValueError:
print("Необходимо ввести число (целое или с точкой).")
price = get_float("Введите цену: ")
discount = get_float("Введите скидку в процентах: ")
final_price = price * (1 - discount / 100)
print(f"Итоговая цена: {final_price:.2f}")
Введите цену: 1500.50 Введите скидку в процентах: 10 Итоговая цена: 1350.45
2. Ввод списка целых чисел через запятую с удалением пробелов
Пользователь может вводить числа, разделённые запятыми, с возможными пробелами.
raw = input("Введите числа через запятую: ") # например: 10, 20, 30
# Разделяем по запятой, убираем пробелы и пустые строки
parts = [p.strip() for p in raw.split(",") if p.strip()]
try:
numbers = [int(p) for p in parts]
print("Квадраты чисел:", [x**2 for x in numbers])
except ValueError:
print("Ошибка: одна из частей не является целым числом.")
Введите числа через запятую: 5, 12, 8 Квадраты чисел: [25, 144, 64]
3. Ввод нескольких значений с помощью цикла до достижения лимита
Пример, когда нужно ввести ровно 5 оценок.
grades = []
for i in range(5):
while True:
try:
grade = float(input(f"Оценка {i+1}: "))
if 0 <= grade <= 100:
grades.append(grade)
break
else:
print("Оценка должна быть от 0 до 100.")
except ValueError:
print("Введите число.")
print("Средняя оценка:", sum(grades)/len(grades))
Оценка 1: 85 Оценка 2: 92 Оценка 3: 78 Оценка 4: 90 Оценка 5: 88 Средняя оценка: 86.6
4. Использование input() с аргументом-приглашением и подавлением новой строки
По умолчанию input() выводит приглашение без перевода строки. После ввода пользователя курсор переходит на новую строку. Если нужно остаться на той же строке, можно использовать sys.stdout.write() и sys.stdin.readline(), но это редко требуется.
import sys
sys.stdout.write("Введите имя: ")
sys.stdout.flush()
name = sys.stdin.readline().strip()
print(f"Привет, {name}!")
Введите имя: Алиса Привет, Алиса!
5. Чтение пароля с маскировкой на Windows (использование msvcrt)
Для платформенно-зависимого скрытого ввода без эха можно использовать модуль msvcrt (только Windows).
import msvcrt
import sys
sys.stdout.write("Введите пароль: ")
pwd = []
while True:
ch = msvcrt.getch()
if ch == b'\r': # Enter
break
elif ch == b'\b': # Backspace
if pwd:
pwd.pop()
sys.stdout.write('\b \b')
else:
pwd.append(ch)
sys.stdout.write('*')
sys.stdout.write('\n')
password = b''.join(pwd).decode()
print("Пароль принят (длина:", len(password), "символов).")
Введите пароль: ********* Пароль принят (длина: 9 символов).
Примечание: Этот код работает только в Windows. В Unix/Linux для аналогичного эффекта используйте getpass.
6. Чтение данных до конца файла (EOF) из перенаправленного ввода
Если программа получает данные через перенаправление (python script.py < input.txt), можно читать до EOF с помощью цикла for по sys.stdin.
import sys
print("Чтение всех строк из stdin (Ctrl+D или EOF для завершения):")
# В интерактивном режиме ввод прекращается по Ctrl+D (Unix) или Ctrl+Z+Enter (Windows)
try:
for line in sys.stdin:
print("Прочитано:", line.rstrip())
except EOFError:
print("\nКонец ввода.")
Чтение всех строк из stdin (Ctrl+D или EOF для завершения): Строка 1 Прочитано: Строка 1 Строка 2 Прочитано: Строка 2 (нажатие Ctrl+D) Конец ввода.
7. Использование input() с таймером (неблокирующий ввод)
В некоторых случаях требуется прервать ожидание ввода, если пользователь бездействует. Для этого в стандартном Python нет простого способа, но можно воспользоваться модулем select (Unix) или threading. Ниже пример с потоком.
import threading
import sys
def get_input():
global user_input
user_input = input("У вас есть 5 секунд для ввода: ")
user_input = None
t = threading.Thread(target=get_input)
t.daemon = True
t.start()
t.join(timeout=5)
if user_input is None:
print("\nВремя вышло.")
else:
print("Вы ввели:", user_input)
У вас есть 5 секунд для ввода: (через 5 секунд без ввода) Время вышло.
Замечание: Такой подход не идеален, так как поток может быть активен после истечения времени, но для простых сценариев подходит.