Библиотека Python разработчика | Книги по питону
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq
نمایش بیشتر📈 تحلیل کانال تلگرام Библиотека Python разработчика | Книги по питону
کانال Библиотека Python разработчика | Книги по питону (@bookpython) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 17 969 مشترک است و جایگاه 7 264 را در دسته فناوری و برنامهها و رتبه 36 611 را در منطقه روسيا دارد.
📊 شاخصهای مخاطب و پویایی
از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 17 969 مشترک جذب کرده است.
بر اساس آخرین دادهها در تاریخ 30 اکتبر, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -95 و در ۲۴ ساعت گذشته برابر -1 بوده و همچنان دسترسی گستردهای حفظ شده است.
- وضعیت تأیید: تأیید نشده
- نرخ تعامل (ER): میانگین تعامل مخاطب 5.36% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 2.75% واکنش نسبت به کل مشترکان کسب میکند.
- دسترسی پستها: هر پست به طور میانگین 963 بازدید دریافت میکند. در اولین روز معمولاً 494 بازدید جمعآوری میشود.
- واکنشها و تعامل: مخاطبان بهطور فعال حمایت میکنند؛ میانگین واکنش به هر پست 4 است.
- علایق موضوعی: محتوا بر موضوعات کلیدی مانند numbers, yield, модуль, none, декоратор تمرکز دارد.
📝 توضیح و سیاست محتوایی
نویسنده این فضا را محل بیان دیدگاههای شخصی توصیف میکند:
“Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍
По всем вопросам @evgenycarter
РКН clck.ru/3Ko7Hq”
به لطف بهروزرسانیهای پرتکرار (آخرین داده در تاریخ 31 اکتبر, 2026)، کانال همواره بهروز و دارای دسترسی بالاست. تحلیلها نشان میدهد مخاطبان بهطور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامهها تبدیل کردهاند.
lst = []. Однако на самом деле вы просто создаёте новый пустой список и присваиваете его переменной lst, а все другие переменные, которые ссылаются на исходный список, продолжают хранить его содержимое.
Пример:
lst = [1, 2, 3]
lst2 = lst
lst = []
print(lst2) # [1, 2, 3]
Хотя это кажется очевидным, правильное решение стало доступно только с введением метода lst.clear() в Python 3.3.
До этого для очистки списка приходилось использовать:
- del lst[:], или
- lst[:] = [].
Оба варианта работают, поскольку срезы позволяют модифицировать часть списка. Если вы берёте срез [:], он охватывает весь список.
Теперь же lst.clear() является более читаемым и современным решением.
👉 @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) для эффективного подсчёта элементов генератора.
👉 @BookPythonrange() в 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 по-прежнему вызывает лёгкую ностальгию.
👉 @BookPython*args и **kwargs для того, чтобы передать в функцию любое количество позиционных и именованных аргументов. Для того, чтобы понять как это работает, сначала познакомимся с тем, что такое распаковка.
👉@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]
👉@BookPython