Python: проверка ввода при чтении и записи файлов
Основные методы проверки ввода в Python
Проверка ввода необходима для защиты программы от некорректных данных. В контексте файлового ввода-вывода это особенно важно: данные из файлов могут содержать ошибки, пустые строки или значения неожиданных типов. Рассмотрим несколько подходов с примерами.
Как универсально проверить ввод на соответствие ожидаемому типу?
Самый надёжный способ - использовать блок try-except для преобразования типов. Пример для чтения чисел из файла:
with open('numbers.txt', 'r') as f:
for line in f:
line = line.strip()
if not line:
continue
try:
value = float(line)
print(f"Обрабатываем {value}")
except ValueError:
print(f"Некорректная строка: {line}")ввод программ на python (ввод данных в программе python)
Этот метод ловит ошибки преобразования и позволяет обработать каждую строку отдельно. Типичные проблемы: пустая строка может быть пропущена через if not line; лишние пробелы удаляются через strip().
Проблема: если файл содержит смешанные типы (целые, дробные, текст), try-except обрабатывает все корректно. Но если ожидается только целое число, лучше сначала проверить наличие десятичной точки. Решение: дополнительная проверка через isdigit() после удаления знака минус для отрицательных чисел.
Как проверить, что строка состоит только из цифр?
Метод str.isdigit() полезен для целых неотрицательных чисел. Пример проверки ввода с клавиатуры:
user_input = input("Введите возраст: ")
if user_input.isdigit():
age = int(user_input)
print(f"Возраст: {age}")
else:
print("Ошибка: введите число без знаков и букв")Python file io (ввод-вывод файлов в python)
Ограничения: isdigit() не распознаёт отрицательные числа, числа с плавающей точкой, не определяет пустую строку. Для файлов, где данные могут начинаться с минуса, метод непригоден. Решение: комбинировать с проверкой знака или использовать регулярные выражения.
Как проверить наличие всех необходимых полей при чтении структурированных данных?
Для CSV-файлов или файлов с разделителями удобно проверять количество полей после разбиения строки. Пример:
with open('data.csv', 'r') as f:
for line in f:
parts = line.strip().split(',')
if len(parts) < 3:
print(f"Пропущена строка: {line}")
continue
name, age, city = parts[0], parts[1], parts[2]
# дополнительная проверка age.isdigit() и т.д.Python temp files (временные файлы в python)
Проблема: лишние пробелы после запятой могут дать некорректные части. Решение: использовать strip() для каждого элемента, либо модуль csv.
Как проверить ввод с помощью регулярных выражений?
Регулярные выражения подходят для форматов: emails, дат, номеров телефонов. Пример проверки email из файла:
import re
email_pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
with open('emails.txt', 'r') as f:
for line in f:
email = line.strip()
if re.match(email_pattern, email):
print(f"Корректный email: {email}")
else:
print(f"Некорректный email: {email}")Python index files (индексация файлов в python)
Сложность: составление точного шаблона. Простой шаблон может пропустить некоторые валидные адреса или ошибочно принять неверные. Рекомендуется использовать библиотеки (например, email-validator) для production.
Как использовать assert для отладки проверки ввода?
Инструкция assert применяется в отладочных целях. Пример проверки, что все числа в файле положительны:
with open('positive.txt', 'r') as f:
for line in f:
line = line.strip()
if line:
num = float(line)
assert num > 0, f"Найдено отрицательное число: {num}"
Важно: assert может быть отключён флагом -O. Он не заменяет полноценную обработку ошибок. Используется только для проверки условий, которые должны быть истинными.
Продвинутые примеры проверки ввода
Рассмотрим более сложные сценарии: проверка дат, диапазонов, использование pydantic и пользовательских исключений.
Как проверить ввод даты из файла?
Пример с модулем datetime:
from datetime import datetime
date_str = "2023-13-01" # пример неверной даты
try:
dt = datetime.strptime(date_str, "%Y-%m-%d")
print(f"Дата корректна: {dt}")
except ValueError:
print(f"Некорректная дата: {date_str}")
Некорректная дата: 2023-13-01
В реальном файле нужно обрабатывать каждую строку аналогично.
Проблема: разные форматы дат. Решение: перебирать несколько форматов в цикле или использовать библиотеку dateutil.
Как проверить, что число находится в заданном диапазоне?
def read_score(line):
try:
score = int(line.strip())
except ValueError:
raise ValueError("Не число")
if not (0 <= score <= 100):
raise ValueError(f"Балл {score} вне диапазона 0-100")
return score
with open('scores.txt', 'r') as f:
for line in f:
try:
score = read_score(line)
print(f"OK: {score}")
except ValueError as e:
print(f"Ошибка: {e}")
Здесь используется пользовательское исключение для ясности.
Как валидировать комплексные структуры данных с помощью Pydantic?
Библиотека pydantic автоматически проверяет типы и ограничения. Пример для JSON-файла:
from pydantic import BaseModel, Field
from typing import List
class Item(BaseModel):
name: str
price: float = Field(ge=0)
class Inventory(BaseModel):
items: List[Item]
# Предположим, data - словарь, полученный из json.load(json_file)
data = {"items": [{"name": "Book", "price": -5}]}
try:
inventory = Inventory(**data)
print(inventory)
except Exception as e:
print(f"Ошибка валидации: {e}")
Ошибка валидации: 1 validation error for Inventory items -> 0 -> price ensure this value is greater than or equal to 0 (type=value_error.number.not_ge; limit_value=0)
Pydantic генерирует понятные сообщения об ошибках и не требует писать проверки вручную.
Как проверить ввод при записи в файл?
Пример функции, которая проверяет данные перед записью:
def save_user(users: list, name: str, age: int):
if not name.strip():
raise ValueError("Имя не может быть пустым")
if not isinstance(age, int) or age < 0:
raise ValueError("Возраст должен быть целым неотрицательным")
with open('users.txt', 'a') as f:
f.write(f"{name.strip()},{age}\n")
try:
save_user([], " ", -5)
except ValueError as e:
print(e)
Имя не может быть пустым