Паттерн "Фабрика исключений"
Централизованное создание исключений:
Упрощает управление ошибками в больших проектах.
Пример:
class ExceptionFactory:
"""Создает стандартизированные исключения"""
@staticmethod
def validation_error(field, message):
return ValueError(f"[VALIDATION] {field}: {message}")
@staticmethod
def business_error(code, message):
error = RuntimeError(message)
error.code = code
return error
# Использование
try:
raise ExceptionFactory.validation_error("email", "Неверный формат")
except ValueError as e:
print(f"Ошибка: {e}") # [VALIDATION] email: Неверный формат
👍2
Модуль unittest для тестирования классов
Базовое тестирование:
Unittest — встроенный модуль для тестирования.
Пример:
import unittest
class Calculator:
def add(self, a, b):
return a + b
class TestCalculator(unittest.TestCase):
def setUp(self):
"""Подготовка перед каждым тестом"""
self.calc = Calculator()
def test_add_positive(self):
self.assertEqual(self.calc.add(2, 3), 5)
def test_add_negative(self):
self.assertEqual(self.calc.add(-1, -1), -2)
if __name__ == "__main__":
unittest.main()
👍2
Mock объекты для тестирования
Изоляция зависимостей:
Mock-объекты имитируют реальные объекты для тестирования.
Пример:
from unittest.mock import Mock
class WeatherService:
def __init__(self, api):
self.api = api
def get_temp(self, city):
return self.api.fetch(city)['temp']
# Тест
mock_api = Mock()
mock_api.fetch.return_value = {'temp': 25}
service = WeatherService(mock_api)
result = service.get_temp("Москва")
assert result == 25
mock_api.fetch.assert_called_once_with("Москва")
👍1👏1
Тестирование наследования
Проверка полиморфного поведения:
Тестируем, что дочерние классы правильно переопределяют методы.
Пример:
class Animal:
def speak(self):
return "Звук"
class Dog(Animal):
def speak(self):
return "Гав"
class TestAnimals(unittest.TestCase):
def test_inheritance(self):
dog = Dog()
self.assertEqual(dog.speak(), "Гав")
self.assertIsInstance(dog, Animal)
👍1👏1
Тестирование приватных методов
Лучше тестировать через публичный интерфейс:
Но иногда нужен прямой доступ.
Пример:
class Validator:
def _validate_email(self, email):
return "@" in email
def register_user(self, email):
if not self._validate_email(email):
raise ValueError("Неверный email")
return True
# Тестируем через публичный метод
validator = Validator()
self.assertTrue(validator.register_user("test@mail.com"))
with self.assertRaises(ValueError):
validator.register_user("invalid-email")
👍2
Паттерн "Тестовые дублеры"
Разные типы дублеров:
Mock, Stub, Fake, Spy для разных задач.
Пример:
from unittest.mock import Mock
class Database:
def get_user(self, user_id):
# Реальный код работы с БД
pass
class UserService:
def __init__(self, db):
self.db = db
def get_user_name(self, user_id):
user = self.db.get_user(user_id)
return user['name'] if user else None
# Используем Mock как тестовый дублер
mock_db = Mock()
mock_db.get_user.return_value = {'name': 'Анна', 'id': 1}
service = UserService(mock_db)
assert service.get_user_name(1) == 'Анна'
👍1🔥1
Дескрипторы
Управление доступом к атрибутам:
Дескрипторы контролируют, как устанавливаются и получаются значения атрибутов.
Пример:
class PositiveNumber:
"""Дескриптор для положительных чисел"""
def __set__(self, obj, value):
if value < 0:
raise ValueError("Число должно быть положительным")
obj.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class Account:
balance = PositiveNumber()
def __init__(self, balance):
self.balance = balance # Вызовет __set__
acc = Account(100) # OK
# acc.balance = -50 # ValueError: Число должно быть положительным
👍2
Слоты slots
Оптимизация памяти:
Ограничивает набор атрибутов и экономит память.
Пример:
class Point:
__slots__ = ['x', 'y'] # Только эти атрибуты разрешены
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(1, 2)
print(p.x, p.y) # 1 2
# p.z = 3 # AttributeError: 'Point' object has no attribute 'z'
👍3
Абстрактные методы
Принудительная реализация:
Абстрактные методы должны быть реализованы в дочерних классах.
Пример:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
"""Должен быть реализован в дочерних классах"""
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self): # Обязательная реализация
return 3.14 * self.radius ** 2
# Shape() # TypeError: нельзя создать экземпляр абстрактного класса
circle = Circle(5) # OK
print(circle.area()) # 78.5
👍2
Протоколы и интерфейсы
Неявные интерфейсы Python:
Если объект имеет нужные методы, он соответствует протоколу.
Пример:
from typing import Protocol
class Drawable(Protocol):
def draw(self) -> str: ...
class Circle:
def draw(self):
return "Рисую круг"
class Square:
def draw(self):
return "Рисую квадрат"
def render(obj: Drawable):
return obj.draw()
print(render(Circle())) # "Рисую круг"
print(render(Square())) # "Рисую квадрат"
👍3
Миксины (Mixins)
Множественное наследование для функциональности:
Миксины добавляют возможности без изменения основной логики.
Пример:
class JSONSerializable:
"""Миксин для сериализации в JSON"""
def to_json(self):
import json
return json.dumps(self.__dict__)
class Timestamped:
"""Миксин для добавления временных меток"""
def __init__(self):
from datetime import datetime
self.created_at = datetime.now()
class User(Timestamped, JSONSerializable):
"""Класс пользователя с миксинами"""
def __init__(self, name, email):
super().__init__() # Вызываем __init__ миксинов
self.name = name
self.email = email
user = User("Анна", "anna@example.com")
print(user.to_json()) # JSON с created_at, name, email
👍4
С Новым 2026 годом! Пусть этот год принесет вам радость, счастье и исполнение всех заветных желаний. Пусть каждый день будет наполнен яркими моментами, новыми достижениями и приятными сюрпризами.
@SV_Python
@SV_Python
🎄5🔥1🤩1