Библиотека Python разработчика | Книги по питону
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq
Ko'proq ko'rsatish📈 Telegram kanali Библиотека Python разработчика | Книги по питону analitikasi
Библиотека Python разработчика | Книги по питону (@bookpython) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 17 973 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 7 274-o'rinni va Rossiya mintaqasida 36 654-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 17 973 obunachiga ega bo‘ldi.
28 Oktabr, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -96 ga, so‘nggi 24 soatda esa -2 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 5.41% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 2.64% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 973 marta ko‘riladi; birinchi sutkada odatda 475 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 4 ta reaksiya keladi.
- Tematik yo‘nalishlar: Kontent numbers, yield, модуль, none, декоратор kabi asosiy mavzularga jamlangan.
📝 Tavsif va kontent siyosati
Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
“Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍
По всем вопросам @evgenycarter
РКН clck.ru/3Ko7Hq”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 29 Oktabr, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.
multiprocessing.Pool
Когда речь заходит о ресурсоемких задачах, которые нагружают ваш CPU, стоит обратить внимание на библиотеку multiprocessing, а именно на класс Pool. Он позволяет задействовать все доступные ядра процессора, автоматически распределяя задачи между ними.
Вот простой пример:
import math
from multiprocessing import Pool
# Генерируем список входных данных
inputs = [i ** 2 for i in range(100, 130)]
# Функция для вычислений
def f(x):
return len(str(math.factorial(x)))
# Последовательное выполнение
%timeit [f(x) for x in inputs]
# Результат: ~1.44 сек
# Параллельное выполнение
p = Pool(4) # Создаем пул из 4 процессов
%timeit p.map(f, inputs)
# Результат: ~451 мс
📲 Мы в MAX
👉@BookPythonLIMIT, например:
SELECT *
FROM table
LIMIT 1001, 100;
Этот запрос действительно вернет 100 записей, с 1001-й по 1100-ю. Но проблема в том, что для базы данных это так же сложно, как и выборка всех первых 1001 записей. Чем дальше запрашиваемая страница, тем медленнее будет выполняться запрос.
Более оптимальным решением является использование фильтрации через WHERE, где клиент передает идентификатор последней записи текущей страницы ($last_seen_id в примере):
SELECT *
FROM table
WHERE id > $last_seen_id
ORDER BY id ASC
LIMIT 100;
Этот подход позволяет избежать сканирования всех предыдущих строк, что значительно ускоряет работу с большими объемами данных.
Если хотите разобраться подробнее, рекомендую почитать отличную статью на эту тему!
📲 Мы в MAX
👉@BookPythonlst = []. Однако на самом деле вы просто создаёте новый пустой список и присваиваете его переменной lst, а все другие переменные, которые ссылаются на исходный список, продолжают хранить его содержимое.
Пример:
lst = [1, 2, 3]
lst2 = lst
lst = []
print(lst2) # [1, 2, 3]
Хотя это кажется очевидным, правильное решение стало доступно только с введением метода lst.clear() в Python 3.3.
До этого для очистки списка приходилось использовать:
- del lst[:], или
- lst[:] = [].
Оба варианта работают, поскольку срезы позволяют модифицировать часть списка. Если вы берёте срез [:], он охватывает весь список.
Теперь же lst.clear() является более читаемым и современным решением.
📲 Мы в MAX
👉@BookPythonrange, поддерживают вызов len():
len(range(10000)) # 10000
Однако генераторы не имеют длины, и попытка вызвать len() вызовет ошибку:
gen = (x ** 2 for x in range(10000))
len(gen) # TypeError: object of type 'generator' has no len()
Стандартное решение: преобразование в список
Один из способов получить размер генератора — это преобразовать его в список:
gen = (x ** 2 for x in range(10000))
print(len(list(gen))) # 10000
Этот подход работает, но имеет серьёзный недостаток: он требует загрузить все значения генератора в память. Если генератор очень большой, это может привести к нехватке памяти.
Более эффективный подход: подсчёт с помощью sum
Чтобы избежать лишнего расхода памяти, можно подсчитать количество элементов в генераторе с использованием sum():
gen = (x ** 2 for x in range(10000))
print(sum(1 for _ in gen)) # 10000
Этот метод обходит генератор "лениво", не создавая дополнительных списков, что делает его идеальным для работы с большими потоками данных.
Резюме
- Используйте len() только для итераторов, поддерживающих его (например, range).
- Для генераторов избегайте преобразования в список, если важна экономия памяти.
- Используйте sum(1 for _ in gen) для эффективного подсчёта элементов генератора.
📲 Мы в MAX
👉@BookPythonrange() в 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 году написал блестящую статью, в которой обосновал преимущества полуоткрытых интервалов. Это не просто удобство — это вопрос корректности и простоты работы с данными.
👉 @BookPython
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*args и **kwargs для того, чтобы передать в функцию любое количество позиционных и именованных аргументов. Для того, чтобы понять как это работает, сначала познакомимся с тем, что такое распаковка.
📲 Мы в MAX
👉@BookPython
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
👉@BookPythonfunctools в Python предоставляет инструменты для работы с функциями, позволяя выполнять различные манипуляции с ними. Вот некоторые из наиболее важных функций и возможностей, которые предоставляет functools:
1. `functools.partial`: Позволяет зафиксировать некоторые аргументы функции и создать новую функцию с предопределенными значениями.
from functools import partial
def multiply(x, y):
return x * y
double = partial(multiply, 2)
print(double(5)) # Вывод: 10
2.`functools.partial`: Применяет функцию к паре элементов в последовательности, сокращая ее до одного значения. Обычно используется для аккумуляции значений.
from functools import reduce
numbers = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, numbers)
print(product) # Вывод: 24
3. functools.lru_cache: Кэширует результаты вызовов функции, чтобы ускорить повторные вызовы с теми же аргументами. Полезно для функций с дорогими вычислениями.
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(10)) # Вывод: 55
4. functools.wraps: Декоратор, который сохраняет метаданные оригинальной функции (такие как имя и документация) при создании декоратора.
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print("Что-то делаем перед вызовом функции")
return func(*args, **kwargs)
return wrapper
@my_decorator
def say_hello():
"""Выводит приветствие."""
print("Привет!")
print(say_hello.__name__) # Вывод: say_hello
print(say_hello.__doc__) # Вывод: Выводит приветствие.
5. functools.total_ordering: Упрощает реализацию всех методов сравнения для класса, определяя только несколько из них.
from functools import total_ordering
@total_ordering
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
def __lt__(self, other):
return (self.x, self.y) < (other.x, other.y)
p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 < p2) # Вывод: True
print(p1 <= p2) # Вывод: True
Эти функции и декораторы делают functools мощным инструментом для функционального программирования в Python.
Мы в MAX
👉@BookPython