Learning Platform
Глоссарий Troubleshooting
Урок 02.07 · 12 мин
Средний
SummarySelf-assessment
Требуемые знания:
  • 01-syntax-and-references
  • 02-pylong-internals
  • 03-float-and-bool
  • 04-pep393-strings
  • 05-operators-and-bigO
  • 06-control-flow-and-cache

Ключевые выводы по основам Python

Мы прошли primitive types на уровне CPython: PyObject, PyLong, PyFloat, PyBool, PyUnicode. Операторы scaled to big-O / amortized analysis. Control flow связан с cache line behavior. Теперь у нас есть инструменты для следующего модуля — структуры данных (list, tuple, dict, set) на том же уровне глубины.


Что мы узнали

  1. Имена → биндинги к PyObject*. Присваивание не копирует объект; оно создаёт ещё одну ссылку с инкрементом ob_refcnt. Cycle GC дополняет refcount для случаев circular references. См. Include/object.h, Modules/gcmodule.c.

  2. int = PyLong = heap-allocated объект с массивом 30-битных digit’ов (ob_digit[]). PyObject_HEAD (16) + ob_size (8) + digits = базовый overhead 24+ байт. Arbitrary precision: ноль overflow ценой constant per-int overhead. См. Objects/longobject.c.

  3. Small-int cache для [-5, 256]: предкэшированные PyLong-объекты в _PyLong_SMALL_INTS. id(256) == id(256) всегда True; id(257) == id(257) обычно False. Optimization для аллокации, не для скорости арифметики.

  4. bool — PyLong subclass. Py_True/Py_False — singletons. True == 1 (значение, через __eq__), True is 1 False (identity, разные объекты). isinstance(True, int) True. См. Objects/boolobject.c.

  5. float = IEEE 754 double (8 байт payload). 1 sign + 11 exp + 52 mantissa бит. 0.1 + 0.2 != 0.3 — round-off, не bug. Для сравнения — math.isclose, для money — decimal.Decimal.

  6. PEP 393 — flexible string representation. Каждая строка выбирает kind = 1, 2 или 4 байта на codepoint в зависимости от max codepoint. ASCII fast path (PyASCIIObject). Одна non-BMP char inflates всю строку до 4 bytes/char. См. Objects/unicodeobject.c.

  7. Big-O — upper bound asymptotic. Amortized analysis для list.append (O(1) amortized, O(n) worst). CPython list_resize использует geometric growth с factor ~1.125 — баланс между memory waste и частотой realloc. См. Objects/listobject.c.

  8. Cache line ≈ 64 bytes на x86_64/aarch64. Sequential access cache-friendly; sequential prefetcher предсказывает. for x in lst быстрее for i in range(len(lst)) из-за fewer bytecodes (FOR_ITER vs FOR_ITER+BINARY_SUBSCR+…) и одинакового cache pattern.

  9. range(N) lazy — 48 байт независимо от N. list(range(N)) материализует.


Что в Module 02 — Структуры данных: внутреннее устройство

Та же глубина, но для composite types:

  • list internals — capacity vs length, geometric realloc, ob_item pointer array.
  • tuple — immutable contiguous, hashable, free-list cache для small tuples.
  • dict — hash function (SipHash для str/bytes), open addressing с perturbation, load factor 2/3.
  • Compact dict (PEP 468) — indices array + entries array, insertion-order preservation.
  • set — same hash table как dict, без values; set operations big-O.
  • Mutability vs immutability на уровне cache locality.

Что в Module 03 — Функции и модули

После Module 02 переходим к функциям:

  • positional / keyword / default / *args / **kwargs.
  • Mutable default argument trap (классический pitfall).
  • Comprehensions vs generator expressions — memory profile.
  • Functional tools: map, filter, functools.reduce, partial, lru_cache.
  • Modules, packages, __name__ == "__main__", sys.modules.

Self-assessment перед Module exam

Прежде чем нажимать «Сдать экзамен», убедитесь, что уверенно объясняете:

  • Разницу между is и ==. Когда корректно использовать is (None / True / False / sentinels), и почему == для значений.
  • Что такое small-int cache, какой у него диапазон и почему id(256) == id(256) всегда True, а id(257) == id(257) обычно False.
  • Почему 0.1 + 0.2 != 0.3, и какой правильный способ сравнить float-значения.
  • Что такое PEP 393 и kinds 1/2/4. Почему добавление одной emoji в ASCII-строку увеличивает её память в 4 раза.
  • Big-O для основных операций: lst.append, lst.insert(0, x), x in lst, x in dict, x in set, dict.__getitem__. Ключевые отличия по сложности.
  • Почему list.append — amortized O(1), а worst-case O(n). Что такое geometric reallocation и какой factor использует CPython.
  • Cache line 64 bytes, sequential prefetcher, и как это связано с тем, что for x in lst быстрее for i in range(len(lst)).
  • Когда is использовать (singleton-проверки) и когда категорически нельзя (значения).

Если что-то непонятно

Возвращайтесь к конкретному уроку:

Не понятноУрок
Имена, биндинги, refcountУрок 1
PyLong, small-int cache, 30-bit digitУрок 2
IEEE 754, machine epsilon, boolУрок 3
PEP 393, ASCII/BMP/non-BMPУрок 4
Big-O cheat-sheet, amortized analysisУрок 5
Cache line, range, bytecodesУрок 6

Module exam ниже — 13 вопросов, passThreshold 70%, можно пересдавать. Если упадёте — studyHint каждого вопроса укажет на конкретный раздел нужного урока. Удачи.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 4. Какое из утверждений о Python primitive types НЕВЕРНО?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7