Пример 1. Абстрактный класс сотрудников
from abc import ABC, abstractmethod
class Employee(ABC):
"""Abstract base class for company employees."""
def __init__(self, name: str) -> None:
self.name = name
@abstractmethod
def work(self) -> None:
"""Describe what the employee does. Must be implemented."""
pass
def take_break(self) -> None:
"""Common behavior for all employees."""
print(f"{self.name} is taking a break.")
class Programmer(Employee):
def work(self) -> None:
print(f"{self.name} writes code.")
class Designer(Employee):
def work(self) -> None:
print(f"{self.name} creates layouts.")
# employee = Employee("Bob") # TypeError!
programmer = Programmer("Alice")
programmer.work()
programmer.take_break()
Что происходит:
Employeeнаследуется отABCи объявляет абстрактный методwork().take_break()— обычный метод, доступный всем наследникам.ProgrammerиDesignerобязаны реализоватьwork().
Пример 2. Пользовательское исключение с данными
class AccessDeniedError(Exception):
"""Raised when the user does not meet age requirements."""
def __init__(self, age: int, min_age: int = 18) -> None:
self.age = age
self.min_age = min_age
super().__init__(f"Access denied: age {age} is below minimum {min_age}")
def check_age(age: int) -> None:
if age < 18:
raise AccessDeniedError(age)
print("Access granted")
try:
check_age(16)
except AccessDeniedError as e:
print("Error:", e)
print("Age:", e.age)
print("Minimum age:", e.min_age)
Пример 3. Исключение на основе ValueError
class TemperatureTooLowError(ValueError):
"""Raised when temperature is below absolute zero."""
pass
def set_temperature(value: float) -> None:
if value < -273.15:
raise TemperatureTooLowError("Temperature cannot be below absolute zero")
print(f"Temperature set to {value}°C")
for temp in (15, -300):
try:
set_temperature(temp)
except TemperatureTooLowError as e:
print("Caught:", e)
except ValueError as e:
# Этот блок тоже сработал бы, потому что TemperatureTooLowError — наследник ValueError
print("Caught as ValueError:", e)
Пример 4. Платёжная система с валидацией
from abc import ABC, abstractmethod
class InvalidPaymentError(Exception):
"""Raised when payment amount is not positive."""
pass
class PaymentProcessor(ABC):
"""Abstract base class for payment processors."""
@abstractmethod
def pay(self, amount: float) -> None:
"""Process a payment of the given amount."""
pass
@staticmethod
def _validate_amount(amount: float) -> None:
"""Guard clause: ensure amount is positive."""
if amount <= 0:
raise InvalidPaymentError("Payment amount must be positive.")
class PaypalPayment(PaymentProcessor):
def pay(self, amount: float) -> None:
self._validate_amount(amount)
print(f"Paid {amount} via PayPal.")
class CreditCardPayment(PaymentProcessor):
def pay(self, amount: float) -> None:
self._validate_amount(amount)
print(f"Paid {amount} via Credit Card.")
payments = [PaypalPayment(), CreditCardPayment()]
for payment in payments:
try:
payment.pay(100)
payment.pay(-50)
except InvalidPaymentError as e:
print("Error:", e)
Почему так: валидация вынесена в статический метод родителя, чтобы не дублировать код в каждом наследнике.
Пример 5. Итератор с нарастающей суммой
class CumulativeSum:
"""Iterator yielding running totals."""
def __init__(self, numbers: list[int]) -> None:
self.numbers = numbers
self.index = 0
self.total = 0
def __iter__(self):
return self
def __next__(self) -> int:
if self.index >= len(self.numbers):
raise StopIteration
self.total += self.numbers[self.index]
self.index += 1
return self.total
data = [3, 5, 2, 4]
for value in CumulativeSum(data):
print(value) # 3 8 10 14
Как запустить в VS Code
- Создайте файл
example.pyв рабочей папке. - Скопируйте код из примера выше.
- Откройте терминал в VS Code (Ctrl + `).
- Убедитесь, что активировано виртуальное окружение:
venv\Scripts\activate(Windows) илиsource venv/bin/activate(Mac/Linux). - Запустите:
python example.py