Библиотека Python разработчика | Книги по питону (@BookPython) — Telegram-канал | Telegram Dialogs
Все каналы
Библиотека Python разработчика | Книги по питону

Библиотека Python разработчика | Книги по питону

@BookPython

18.2K подписчиков технологии 💬 Комментарии открыты

Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq

Последние публикации

Библиотека Python разработчика | Книги по питону
17.07.2026 13:17 · 👁 389
Почему range() в Python использует полуоткрытые интервалы? Функция range() в Python работает с полуоткрытыми интервалами. Например, range(2, 10) задаёт числа в диапазоне [2, 10), то есть [2, 3, 4, 5, 6, 7, 8, 9]. На первый взгляд это может показаться неочевидным или асимметричным, но у такого подхода есть свои преимущества. Почему полуоткрытые интервалы? Полуоткрытые интервалы позволяют легко "склеивать" смежные диапазоны без риска ошибок на единицу: - Если a = 2, b = 5, и c = 10, то [a, c) можно выразить как: [a, c) = [a, b) + [b, c) Это работает идеально, потому что конец одного интервала (`b`) автоматически становится началом следующего. В случае закрытых интервалов, такая "склейка" требует дополнительной обработки: [a, c] = [a, b] + [b+1, c] Связь с индексацией с нуля Индексация с нуля в Python также связана с этим принципом. Рассмотрим диапазон range(0, N): - Этот диапазон включает ровно N элементов, что делает код более предсказуемым: for i in range(0, N): print(i) Здесь i проходит значения от 0 до N-1, что логично и удобно. Преимущества для работы с массивами Полуоткрытые интервалы идеально подходят для работы с индексами массивов: arr = [10, 20, 30, 40, 50] print(arr[1:3]) # [20, 30] Интервал [1:3) охватывает элементы с индексами 1 и 2, но не 3, что упрощает вычисления границ. Исторический контекст Этот подход имеет глубокие корни в компьютерной науке. Эдсгер Дейкстра, один из пионеров программирования, в 1982 году написал блестящую статью, в которой обосновал преимущества полуоткрытых интервалов. Это не просто удобство — это вопрос корректности и простоты работы с данными. 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
16.07.2026 16:08 · 👁 575
Распаковка параметров функций в Python 2 и 3 В Python 2 существовала интересная возможность распаковывать параметры функций прямо в их определении. Пример: def between(x, (start, stop)): return start < x < stop interval = (5, 10) print(between(2, interval)) # False print(between(7, interval)) # True Более того, это работало даже рекурсивно: def determinant_2_x_2(((a, b), (c, d))): return a * d - c * b matrix = [ (1, 2), (3, 4), ] print(determinant_2_x_2(matrix)) # -2 Но начиная с Python 3, эта возможность была удалена из языка. Чтобы добиться того же результата, теперь нужно распаковывать параметры вручную: def determinant_2_x_2(matrix): row1, row2 = matrix a, b = row1 c, d = row2 return a * d - c * b matrix = [ (1, 2), (3, 4), ] print(determinant_2_x_2(matrix)) # -2 Удаление этой функциональности сделало код более явным и читаемым, но для любителей компактности Python 2 по-прежнему вызывает лёгкую ностальгию. 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
15.07.2026 06:02 · 👁 722
Если вы хотите игнорировать какое-то исключение, вы, вероятно, сделаете что-то вроде этого: try: lst = [1, 2, 3, 4, 5] print(lst[10]) except IndexError: pass Это будет работать (ничего не выводя), но contextlib позволяет сделать то же самое более выразительно и семантически правильно: from contextlib import suppress with suppress(IndexError): lst = [1, 2, 3, 4, 5] lst[10] 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
13.07.2026 04:56 · 👁 903
Что такое контекстный менеджер в Python? Контекстный менеджер в Python - это специальный тип объекта, который определяет методы enter() и exit() и используется с инструкцией with. Эти объекты часто применяются в операциях, которые требуют установки и освобождения ресурсов.  Частый сценарий - это работа с файлом: with open('file.txt', 'r') as file: data = file.read() Здесь контекстный менеджер гарантирует, что файл будет корректно закрыт после завершения блока with, даже если при чтении файла возникнет исключение. Вот как можно написать простой контекстный менеджер самостоятельно: import time class Timer: def __enter__(self): self.start = time.time() def __exit__(self, exc_type, exc_val, exc_tb): self.end = time.time() print(f'Время выполнения: {self.end - self.start:.2f} секунд') with Timer(): # код, время выполнения которого нужно измерить time.sleep(2) 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
10.07.2026 06:45 · 👁 988
В Python вы можете переопределить оператор квадратных скобок ([]), определив магический метод getitem. Примером может быть объект Cycle, который виртуально содержит бесконечное количество повторяющихся элементов: class Cycle: def __init__(self, lst): self._lst = lst def __getitem__(self, index): return self._lst[index % len(self._lst)] print(Cycle(['a', 'b', 'c'])[100]) # prints 'b' Необычность здесь заключается в том, что оператор [] поддерживает уникальный синтаксис. Он может использоваться не только так — [2], но и так — [2:10], или [2:10:2], или [2::2], или даже [:]. Семантика — [start:stop:step], но вы можете применять её так, как вам нужно, для ваших собственных объектов. Но что же получает getitem в качестве параметра index, если использовать этот синтаксис? Для этого существуют объекты slice. In : class Inspector: ...: def __getitem__(self, index): ...: print(index) ...: In : Inspector()[1] 1 In : Inspector()[1:2] slice(1, 2, None) In : Inspector()[1:2:3] slice(1, 2, 3) In : Inspector()[:] slice(None, None, None) Вы даже можете комбинировать синтаксис кортежей и срезов: In : Inspector()[:, 0, :] (slice(None, None, None), 0, slice(None, None, None)) Slice не делает ничего, кроме как просто хранит атрибуты start, stop и step. In : s = slice(1, 2, 3) In : s.start Out: 1 In : s.stop Out: 2 In : s.step Out: 3 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
08.07.2026 19:10 · 👁 1K
Вредные советы python разработчику l=[['a', 'b', 'c'], ['1', '2'], ['#']] sum(l, []) В Python можно выпрямить вложенные списки с помощью... функции sum(). Вот код (выполнять, пока никто не видит): Дело в том, что sum() принимает первым аргументом итерируемый объект, а вторым — значение, с которого начинается операция. По умолчанию это 0, но если указать пустой список [], то sum() начнёт с него. Затем sum() последовательно применяет операцию сложения к элементам первого аргумента, начиная со значения второго аргумента. В случае списков это означает конкатенацию. 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
08.07.2026 05:40 · 👁 1K
Функция enumerate Эта встроенная функция снабжает циклы счётчиком. Возвращает генераторный объект, который имеет метод, вызываемый встроенной функцией next: на каждом проходе цикла возвращает кортеж {индекс, значение}. Цикл for проходит по этим кортежам автоматически, что позволяет распаковывать их значения с помощью присваивания кортежей почти так, как в zip. S = "stroka" example = enumerate(S) next(example) # -> (0, 's') Пример использования: shopping_list = ['яблоки', 'бананы', 'апельсины', 'хлеб'] for index, item in enumerate(shopping_list, start=1): print(f"Пункт {index}: {item}") 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
06.07.2026 04:51 · 👁 1.1K
Очередь с приоритетом — это структура данных, которая поддерживает две операции: добавление элемента и извлечение минимального из всех ранее добавленных элементов. Одной из самых распространённых реализаций очереди с приоритетом является бинарная куча. Это полное бинарное дерево со следующим свойством: ключ, хранящийся в каждом узле, меньше или равен (≤) ключам в дочерних узлах. Минимум всех элементов находится в корне такого дерева. 1 3 7 5 4 9 8 15 16 17 18 19 В бинарной куче сложность операций вставки и извлечения составляет O(log n). Обычный способ хранения полного бинарного дерева в памяти — это массив, где дочерние элементы для x[i] находятся в x[2*i+1] и x[2*i+2]. [1, 3, 7, 5, 4, 9, 8, 15, 16, 17, 18, 19] В Python нет бинарной кучи в виде класса, но предоставляется ряд функций, которые позволяют использовать список как бинарную кучу. Эти функции находятся в модуле heapq. In [1]: from heapq import * In [2]: heap = [3,2,1] In [3]: heapify(heap) In [4]: heap Out[4]: [1, 2, 3] In [5]: heappush(heap, 0) In [6]: heap Out[6]: [0, 1, 3, 2] In [7]: heappop(heap) Out[7]: 0 In [8]: heap Out[8]: [1, 2, 3] 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
03.07.2026 05:54 · 👁 1.2K
Если вы хотите перехватить как IndexError, так и KeyError, вы можете и должны использовать LookupError, их общего предка. Это оказалось полезным при доступе к сложным вложенным данным. try: db_host = config['databases'][0]['hosts'][0] except LookupError: db_host = 'localhost' 📲 Мы в MAX 👉@BookPython
Библиотека Python разработчика | Книги по питону
02.07.2026 06:16 · 👁 1.3K
>>> exit Use exit() or Ctrl-D (i.e. EOF) to exit Вы когда-нибудь задумывались, почему при попытке выйти из интерактивного Python с помощью простого exit или quit появляется это сообщение? Решение довольно неожиданное, но изящное. Это не специальный случай для интерактивной оболочки, она просто показывает представление каждого вычисленного результата, а эта строка - просто представление функции exit. Строго говоря, вы не должны использовать exit в своих повседневных проектах, поскольку она была создана специально для интерактивной оболочки. Вместо этого используйте sys.exit(). 📲 Мы в MAX 👉@BookPython
Чат поддержки
Ответим здесь же, обычно быстро
Здравствуйте! Напишите ваш вопрос — оператор ответит в этом чате.