Домашнє завдання

Dataclass і сучасний стиль

Предметна область тут інша, ніж у лекції, — навмисно: якщо ти зможеш повторити ту саму механіку на своїх даних, значить, справа не в завченому прикладі. Працюємо з карткою читача бібліотеки. Усе роби в окремому файлі chytachi.py або в новому зошиті — практику не редагуй, вона знадобиться для звірки.


рівень 1Рівень 1 — База

Опиши картку читача через @dataclass і доведи, що фабрика справді створює окремий список кожному.

  1. Клас Читач із полями: імʼя (рядок), рік_народження (ціле), квиток (рядок), взяті_книги (список, порожній за замовчуванням).
  2. Спершу напиши взяті_книги: list = [] і збережи текст помилки в коментарі — слово в слово. Потім полагодь через field(default_factory=list).
  3. Створи двох читачів, додай книгу одному з них, надрукуй обох.
  4. Надрукуй list(Читач.__dataclass_fields__) і repr одного читача.

Зроблено, якщо:


рівень 2Рівень 2 — Плюс

Додай до картки правила, яких декоратор згенерувати не може.

  1. Напиши __post_init__, який кидає ValueError, якщо: імʼя порожнє або складається з пробілів; рік_народження поза межами 1900–2026.
  2. Додай поле вік: int = field(init=False) і обчисли його в тому ж __post_init__ (вважай поточним 2026 рік).
  3. Додай службове поле останній_вхід: float = field(default=0.0, compare=False) — воно не має впливати на рівність двох карток.
  4. Перевір, що поле вік неможливо передати в конструктор.

Зроблено, якщо:


рівень 3Рівень 3 — Виклик

Дослідь межу незмінності й доведи її числами, а не словами.

  1. Зроби ЗамороженийЧитач через @dataclass(frozen=True) з тими самими полями, де взяті_книгисписок. Доведи двома assert-ами: (а) поле не перепризначити, (б) список усередині все одно змінюється методом append.
  2. Покажи, що такий обʼєкт не хешується, і що падає при цьому не Читач, а list: злови TypeError і перевір, що в тексті є слово list.
  3. Зроби другу версію, де взяті_книги — кортеж. Доведи, що тепер hash() працює, а дві однакові картки в множині зливаються в одну.
  4. Зміряй tracemalloc-ом памʼять на 200 000 карток для чотирьох варіантів: звичайний @dataclass, @dataclass(slots=True), NamedTuple і звичайний клас із __init__. Побудуй табличку «байтів на обʼєкт» і випиши висновок одним реченням.
  5. Знайди й опиши випадок, коли NamedTuple не підходить, а dataclass підходить, і підкріпи його кодом на пʼять рядків.

Зроблено, якщо:


Підказки