Перейти к основному содержимому

ДЗ 3 — Углубленное ООП и дескрипторы

📚 Лекция: Углубленное ООП

Тема и дедлайн

Тема курса: модуль 4 (углубленное ООП) Дедлайн: 16 апреля 2026, 23:59 Classroom: Принять задание


3.1 — Класс Matrix с магическими методами (2 балла) ★★☆

Реализуй класс Matrix с полным набором поддерживаемых операций.

Обязательные методы:

m = Matrix([[1, 2], [3, 4]])

# Арифметика
m1 + m2 # __add__
m1 - m2 # __sub__
m * 3.0 # __mul__ (скалярное)
m1 @ m2 # __matmul__ (матричное)

# Сравнение и хэширование
m1 == m2 # __eq__
hash(m) # __hash__ (матрица должна быть hashable)

# Представление
repr(m) # __repr__: Matrix([[1, 2], [3, 4]])
str(m) # __str__: читаемое табличное представление

# Форматирование
f"{m:.2f}" # __format__: все элементы с заданной точностью

# Контекстный менеджер для файлов
with Matrix.from_file("matrix.txt") as m:
result = m @ m

Формат файла для from_file: числа через пробел, строки через перенос.

Зачем это

Понимание того, как Python использует dunder-методы для интеграции объектов с синтаксисом языка — ключевая идея всего курса.


3.2 — Дескрипторы атрибутов (3 балла) ★★★

Реализуй дескрипторы своего варианта и примени их к атрибутам класса.

Варианты (3 дескриптора по калькулятору):

#ДескрипторПоведение
0ValidatedПроверяет тип и диапазон при записи, поднимает TypeError/ValueError
1LoggedЛогирует каждое обращение (__get__) и изменение (__set__) в logging
2CachedЛенивое вычисление: считается при первом обращении, далее из кэша
3TypedСтрогая проверка типа при записи (без диапазона)
4ReadOnlyРазрешает запись только один раз, далее AttributeError
5ObservableХранит список callback-функций, вызывает их при изменении значения

Каждый дескриптор должен реализовывать __set_name__, __get__, __set__.

Пример применения:

class Matrix:
rows = Validated(type=int, min=1)
cols = Validated(type=int, min=1)
determinant = Cached() # вычисляется лениво при первом m.determinant
data = Logged() # логирует все обращения
Зачем это

Дескрипторы — механизм, на котором построены @property, @classmethod, @staticmethod и поля Django/SQLAlchemy. Понимание дескрипторов = понимание того, как работает ООП в Python на самом деле.


3.3 — Хэширование и коллизии (2 балла) ★★☆

Используя класс Matrix из задания 3.1:

  1. Помести несколько матриц в set и dict в качестве ключей — убедись что это работает
  2. Намеренно создай коллизию хэша: две разные матрицы с одинаковым hash(), но m1 != m2
  3. Продемонстрируй, что Python корректно разрешает коллизию (обе матрицы хранятся в set)
  4. Напиши в комментарии: почему важен инвариант a == b → hash(a) == hash(b) и что произойдёт, если его нарушить

Артефакт: файл hw03/collision_demo.py с демонстрацией и объяснением.

Зачем это

__hash__ и __eq__ — один из самых частых источников багов в Python. Понимание этой пары обязательно для любого разработчика.


Итого

ЗадачаБаллы
3.1 Matrix с магическими методами2
3.2 Дескрипторы3
3.3 Хэширование и коллизии2
Итого7