1616- ** Кросплатформеність** : один код працює на Linux, macOS, Windows.
1717- ** Мультипарадигменність** : procedural, OOP, functional підходи в одному проєкті.
1818- ** Сильна екосистема** : ` pip ` , ` venv ` , ` pyproject.toml ` , тисячі готових бібліотек.
19- - ** Сучасні можливості Python 3.14 +** : type hints, ` dataclass ` , ` async/await ` , ` match/case ` , генератори, context managers.
19+ - ** Сучасні можливості Python 3.10 +** : type hints, ` dataclass ` , ` async/await ` , ` match/case ` , генератори, context managers.
2020
2121Приклад production-style функції:
2222
@@ -36,7 +36,7 @@ def process_users(users: list[User]) -> list[str]:
3636
3737- Python прискорює розробку завдяки простому синтаксису та великій стандартній бібліотеці.
3838- Мова підходить для backend, automation, data/ML, тестування та DevOps.
39- - У Python 3.14 + ключові практики: type hints, async IO, сучасний standard library.
39+ - У Python 3.10 + ключові практики: type hints, async IO, сучасний standard library.
4040
4141</details >
4242
@@ -1681,13 +1681,20 @@ a == b # True
16811681a is b # False
16821682```
16831683
1684+ ** Важливо про оптимізації (Interning):**
1685+ CPython кешує ("інтернує") малі цілі числа (від -5 до 256) та короткі рядки
1686+ на етапі компіляції/завантаження. Тому для них ` is ` може повертати ` True ` ,
1687+ навіть якщо вони створені окремо. Але це деталі реалізації, на які не варто
1688+ покладатися в бізнес-логіці.
1689+
16841690Для ` None ` завжди використовуйте ` is ` .
16851691
16861692** Коротко:**
16871693
16881694- ` == ` про рівність значень.
1689- - ` is ` про той самий об'єкт.
1690- - ` value is None ` це правильний стиль перевірки.
1695+ - ` is ` про той самий об'єкт у пам'яті.
1696+ - Interning може давати неочевидний ` is True ` для малих ` int ` та ` str ` .
1697+ - ` value is None ` — це єдиний правильний стиль для перевірки на ` None ` .
16911698
16921699</details >
16931700
@@ -2064,7 +2071,10 @@ Python використовує правило LEGB для пошуку імен
20642071найближчого enclosing-scope (не глобального).
20652072
20662073``` python
2067- def counter () -> callable :
2074+ from collections.abc import Callable
2075+
2076+
2077+ def counter () -> Callable:
20682078 value = 0
20692079
20702080 def inc () -> int :
@@ -2876,7 +2886,7 @@ class User:
28762886 self .name = name
28772887
28782888 @ classmethod
2879- def from_email (cls , email : str ) -> " User" :
2889+ def from_email (cls , email : str ) -> User:
28802890 return cls (email.split(" @" )[0 ])
28812891```
28822892
@@ -2971,11 +2981,21 @@ class Point:
29712981 self .y = y
29722982```
29732983
2984+ ** Нюанси використання:**
2985+
2986+ - ** Економія пам'яті:** об'єкти займають значно менше місця, бо атрибути
2987+ зберігаються у фіксованому масиві, а не в хеш-таблиці ` __dict__ ` .
2988+ - ** Швидкість:** доступ до атрибутів у ` __slots__ ` зазвичай трохи швидший.
2989+ - ** Відсутність ` __dict__ ` :** ви не зможете динамічно додавати нові атрибути,
2990+ яких немає у списку ` __slots__ ` (якщо тільки не додати ` "__dict__" ` у сам список).
2991+ - ** Слабкі посилання:** якщо ви хочете використовувати ` weakref ` , потрібно
2992+ явно додати ` "__weakref__" ` у ` __slots__ ` .
2993+
29742994** Коротко:**
29752995
2976- - ` __slots__ ` корисний для великої кількості легковагових об'єктів.
2977- - Дає memory-оптимізацію і контроль атрибутів .
2978- - Зменшує гнучкість динамічного додавання полів .
2996+ - ` __slots__ ` корисний для мільйонів легковагових об'єктів (напр. вузли графа) .
2997+ - Прибирає ` __dict__ ` і ` __weakref__ ` за замовчуванням .
2998+ - Зменшує гнучкість на користь продуктивності та контролю .
29792999
29803000</details >
29813001
@@ -3276,12 +3296,28 @@ class C(A, B): ...
32763296MRO визначає порядок пошуку методів у ієрархії класів.
32773297У Python використовується алгоритм C3 linearization.
32783298
3299+ ** Diamond Problem (Проблема алмазу):**
3300+ Це класичний випадок, коли клас ` D ` успадковується від ` B ` та ` C ` , які обидва
3301+ успадковуються від ` A ` . MRO гарантує, що ` A ` буде переглянутий лише після того,
3302+ як будуть переглянуті всі його нащадки (` B ` та ` C ` ).
3303+
3304+ ``` python
3305+ class A : pass
3306+ class B (A ): pass
3307+ class C (A ): pass
3308+ class D (B , C ): pass
3309+
3310+ print (D.mro())
3311+ # [D, B, C, A, object]
3312+ ```
3313+
32793314Переглянути порядок можна через ` ClassName.__mro__ ` або ` ClassName.mro() ` .
32803315
32813316** Коротко:**
32823317
32833318- MRO вирішує, з якого базового класу брати метод.
32843319- Порядок передбачуваний і формально визначений (C3).
3320+ - Завдяки MRO Python коректно обробляє Diamond Problem.
32853321- Для cooperative inheritance всі класи мають викликати ` super() ` .
32863322
32873323</details >
@@ -3614,7 +3650,9 @@ class Field:
36143650``` python
36153651from dataclasses import dataclass
36163652@dataclass (slots = True )
3617- class User : name: str ; active: bool = True
3653+ class User :
3654+ name: str
3655+ active: bool = True
36183656```
36193657
36203658** Коротко:**
@@ -4458,7 +4496,6 @@ dir(math)
44584496- Варто добре знати stdlib перед додаванням сторонніх пакетів.
44594497
44604498</details >
4461-
44624499<details >
44634500<summary >200. Що ви знаєте про пакет `collections`, які ще built-in modules використовувались?</summary >
44644501
@@ -4532,7 +4569,7 @@ random.shuffle(items)
45324569** Коротко:**
45334570
45344571- ` shuffle ` змінює оригінальний список.
4535- - Працює лише зі списками (mutable sequence ).
4572+ - Працює лише з мутабельними послідовностями (наприклад, списками ).
45364573- Для нової копії: ` random.sample(items, k=len(items)) ` .
45374574
45384575</details >
@@ -4581,7 +4618,7 @@ Virtual environment це ізольоване середовище Python із
45814618
45824619- Формат простий і сумісний з ` pip install -r ` .
45834620- Найкраще фіксувати точні версії для production.
4584- - Часто генерується з lock-файлів.
4621+ - Часто генерується інструментами (наприклад, ` pip-tools ` або ` poetry export ` ) з декларативного переліку/ lock-файлів.
45854622
45864623</details >
45874624
@@ -5213,11 +5250,17 @@ CPU-bound задачі переважно витрачають час на об
52135250` asyncio ` запускає event loop, який виконує tasks (coroutines), перемикаючись у
52145251точках ` await ` і плануючи готові операції I/O.
52155252
5253+ ** Критичне правило:**
5254+ Event loop працює в одному потоці.
5255+ Будь-яка блокувальна операція (` time.sleep() ` , синхронні
5256+ запити ` requests ` , важкі обчислення) зупиняє ** весь** цикл
5257+ і всі інші задачі.
5258+
52165259** Коротко:**
52175260
5218- - Один потік може обслуговувати багато I/O задач.
5219- - Планування кооперативне, не preemptive.
5220- - Блокувальні виклики потрібно виносити з loop .
5261+ - Один потік може обслуговувати багато I/O задач через кооперативність .
5262+ - Планування не витісняє задачі (non- preemptive) .
5263+ - Блокувальні виклики вбивають продуктивність asyncio .
52215264
52225265</details >
52235266
@@ -5266,10 +5309,16 @@ Event loop це планувальник, який відстежує події
52665309Коли workload CPU-bound або основні бібліотеки блокувальні й не мають async API.
52675310Також не окупається для простих коротких скриптів.
52685311
5312+ ** Вирішення для блокуючого коду:**
5313+ Якщо потрібно використати блокуючу бібліотеку в async-середовищі,
5314+ використовуйте ` loop.run_in_executor(None, sync_func) ` ,
5315+ що запустить її в окремому потоці, не блокуючи event loop.
5316+
52695317** Коротко:**
52705318
52715319- Async не прискорює чисті обчислення.
52725320- Без неблокувальних I/O бібліотек вигода мінімальна.
5321+ - ` run_in_executor ` допомагає інтегрувати legacy/sync код.
52735322- Складність async має бути виправдана навантаженням.
52745323
52755324</details >
0 commit comments