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

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

Open in Telegram

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

Show more

📈 Analytical overview of Telegram channel Библиотека Python разработчика | Книги по питону

Channel Библиотека Python разработчика | Книги по питону (@bookpython) in the Russian language segment is an active participant. Currently, the community unites 18 326 subscribers, ranking 7 317 in the Technologies & Applications category and 36 872 in the Russia region.

📊 Audience metrics and dynamics

Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 18 326 subscribers.

According to the latest data from 05 June, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -86 over the last 30 days and by -1 over the last 24 hours, overall reach remains high.

  • Verification status: Not verified
  • Engagement rate (ER): The average audience engagement rate is 6.08%. Within the first 24 hours after publication, content typically collects 2.60% reactions from the total number of subscribers.
  • Post reach: On average, each post receives 1 114 views. Within the first day, a publication typically gains 477 views.
  • Reactions and interaction: The audience actively supports content: the average number of reactions per post is 2.
  • Thematic interests: Content is focused on key topics such as numbers, yield, модуль, none, декоратор.

📝 Description and content policy

The author describes the resource as a platform for expressing subjective opinions:
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq

Thanks to the high frequency of updates (latest data received on 06 June, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.

18 326
Subscribers
-124 hours
-277 days
-8630 days
Posts Archive
Розыгрыш книги «Peter Lindbergh» от СШД Разыгрываем книгу Peter Lindberg. On Fashion Photography (40th Edition) Если вы работаете с визуалом, то имя Питера Линбрерга вам точно знакомо. А если пока не знакомо - вот хороший повод это исправить. В этой книге больше 300 его съемок за 40 лет. Здесь и "белые рубашки" с Малибу, и Comme des Garçons , и первая обложка Vogue для Анны Винтур. Модели, актеры, дизайнеры, но фокус всегда один: человек в кадре. Очень полезная книга, если вы работаете с модой, съемками, сторителлингом или визуальной идентичностью. Как участвовать? Быть подписанным на наш канал в Telegram Напиши в комменатриях СДШ Подписаться #реклама 16+ О рекламодателе

Чтобы отсортировать словарь по его значениям, используйте функцию sorted с пользовательской функцией ключа:

>>> d = dict(a=1, c=3, b=2)
>>> sorted(d.items(), key=lambda item: item[1])
[('a', 1), ('b', 2), ('c', 3)]
Однако такая функция уже существует в модуле operator:

>>> from operator import itemgetter
>>> sorted(d.items(), key=itemgetter(1))
[('a', 1), ('b', 2), ('c', 3)]
Вы также можете сортировать только ключи вместо пар ключ-значение:

>>> sorted(d, key=lambda k: d[k])
['a', 'b', 'c']
И снова, эту лямбду можно заменить уже существующим методом:

>>> sorted(d, key=d.get)
['a', 'b', 'c']
👉@BookPython

А вы практикуете PRACTIM? Мы все нуждаемся в ассистентах для выполнения задач на работе. Но часто результат нашей работы зависит от эмоционального состояния. А что, если и здесь нам нужен ассистен? PRACTIM— это именно он!⚡ И это будущее ментального здоровья Попробовать #реклама О рекламодателе

🚀 Подборка Telegram каналов для программистов Системное администрирование, DevOps 📌 https://t.me/bash_srv Bash Советы https://t.me/win_sysadmin Системный Администратор Windows https://t.me/sysadmin_girl Девочка Сисадмин https://t.me/srv_admin_linux Админские угодья https://t.me/linux_srv Типичный Сисадмин https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin https://t.me/linux_odmin Linux: Системный администратор https://t.me/devops_star DevOps Star (Звезда Девопса) https://t.me/i_linux Системный администратор https://t.me/linuxchmod Linux https://t.me/sys_adminos Системный Администратор https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало) https://t.me/sysadminof Книги для админов, полезные материалы https://t.me/i_odmin Все для системного администратора https://t.me/i_odmin_book Библиотека Системного Администратора https://t.me/i_odmin_chat Чат системных администраторов https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др. https://t.me/sysadminoff Новости Линукс Linux 1C разработка 📌 https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С https://t.me/DevLab1C 1С:Предприятие 8 https://t.me/razrab_1C 1C Разработчик https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт https://t.me/rabota1C_rus Вакансии для программистов 1С Программирование C++📌 https://t.me/cpp_lib Библиотека C/C++ разработчика https://t.me/cpp_knigi Книги для программистов C/C++ https://t.me/cpp_geek Учим C/C++ на примерах Программирование Python 📌 https://t.me/pythonofff Python академия. https://t.me/BookPython Библиотека Python разработчика https://t.me/python_real Python подборки на русском и английском https://t.me/python_360 Книги по Python Java разработка 📌 https://t.me/BookJava Библиотека Java разработчика https://t.me/java_360 Книги по Java Rus https://t.me/java_geek Учим Java на примерах GitHub Сообщество 📌 https://t.me/Githublib Интересное из GitHub Базы данных (Data Base) 📌 https://t.me/database_info Все про базы данных Мобильная разработка: iOS, Android 📌 https://t.me/developer_mobila Мобильная разработка https://t.me/kotlin_lib Подборки полезного материала по Kotlin Фронтенд разработка 📌 https://t.me/frontend_1 Подборки для frontend разработчиков https://t.me/frontend_sovet Frontend советы, примеры и практика! https://t.me/React_lib Подборки по React js и все что с ним связано Разработка игр 📌 https://t.me/game_devv Все о разработке игр Библиотеки 📌 https://t.me/book_for_dev Книги для программистов Rus https://t.me/programmist_of Книги по программированию https://t.me/proglb Библиотека программиста https://t.me/bfbook Книги для программистов БигДата, машинное обучение 📌 https://t.me/bigdata_1 Big Data, Machine Learning Программирование 📌 https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций https://t.me/rust_lib Полезный контент по программированию на Rust https://t.me/golang_lib Библиотека Go (Golang) разработчика https://t.me/itmozg Программисты, дизайнеры, новости из мира IT https://t.me/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 https://t.me/nodejs_lib Подборки по Node js и все что с ним связано https://t.me/ruby_lib Библиотека Ruby программиста https://t.me/lifeproger Жизнь программиста. Авторский канал. QA, тестирование 📌 https://t.me/testlab_qa Библиотека тестировщика Шутки программистов 📌 https://t.me/itumor Шутки программистов Защита, взлом, безопасность 📌 https://t.me/thehaking Канал о кибербезопасности https://t.me/xakep_2 Хакер Free Книги, статьи для дизайнеров 📌 https://t.me/ux_web Статьи, книги для дизайнеров Математика 📌 https://t.me/Pomatematike Канал по математике https://t.me/phis_mat Обучающие видео, книги по Физике и Математике https://t.me/matgeoru Математика | Геометрия | Логика Excel лайфхак📌 https://t.me/Excel_lifehack https://t.me/mir_teh Мир технологий (Technology World) Вакансии 📌 https://t.me/sysadmin_rabota Системный Администратор https://t.me/progjob Вакансии в IT

Все объекты в Python создаются с помощью вызова метода __new__. Даже если вы определяете собственный __new__ для своего класса, вам всё равно нужно вызвать super().__new__(...). Можно подумать, что object.__new__ — это базовая реализация, которая отвечает за создание всех объектов. Но это не совсем так. На самом деле существует несколько таких реализаций, и они несовместимы между собой. Например, у dict есть собственная низкоуровневая реализация __new__, и объекты типов, унаследованных от dict, нельзя создать с помощью object.__new__:

class D(dict):
    pass

class A:
    pass

object.__new__(A)
# <__main__.A at 0x7f200c8902e8>

object.__new__(D)
# TypeError: object.__new__(D) is not safe,
# use D.__new__()
👉@BookPython

Каждый вызов next(x) возвращает следующее значение из итератора x, если только не возникает исключение. Если это StopIteration, значит, итератор исчерпан и больше не может возвращать значения. При итерации по генератору это исключение выбрасывается автоматически в конце его тела:

>>> def one_two():
...     yield 1
...     yield 2
...
>>> i = one_two()
>>> next(i)
1
>>> next(i)
2
>>> next(i)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
StopIteration автоматически обрабатывается инструментами, которые вызывают next за вас:

>>> list(one_two())
[1, 2]
Проблема в том, что любое неожиданное StopIteration, возникшее внутри генератора, приводит к его молчаливому завершению, а не к выбросу исключения:

def one_two():
    yield 1
    yield 2

def one_two_repeat(n):
    for _ in range(n):
        i = one_two()
        yield next(i)
        yield next(i)
        yield next(i)

print(list(one_two_repeat(3)))
Последний yield здесь — ошибка: StopIteration вызывается и прерывает list(...). В результате получаем [1, 2], что может удивить. Однако это поведение было изменено в Python 3.7. Теперь любое внешнее StopIteration, возникшее в генераторе, преобразуется в RuntimeError:

Traceback (most recent call last):
  File "test.py", line 10, in one_two_repeat
    yield next(i)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print(list(one_two_repeat(3)))
RuntimeError: generator raised StopIteration
Такое же поведение можно включить начиная с Python 3.5 с помощью:

from __future__ import generator_stop
👉@BookPython

ТИМИ-2025: Встреча профессионалов в области ТИМ Конференция, где говорят на языке практиков. Общение САПР-профессионалов! ✅Ка
ТИМИ-2025: Встреча профессионалов в области ТИМ Конференция, где говорят на языке практиков. Общение САПР-профессионалов! ✅Как внедрить Model Studio CS в текущие процессы проектирования ✅Личный разговор с разработчиками и пользователями Model Studio CS и CADLib ✅Сравните ваш подход с методиками ведущих компаний Конференция 19 июня | Бесплатно | Подключайтесь из любой точки страны! Зарегистрироваться #реклама 16+ timi-conf.ru О рекламодателе

Некоторый код может выводить интересующие вас данные в stdout, вместо того чтобы предоставлять API, возвращающий строку, пригодную для использования в программе. Вместо рефакторинга такого кода можно воспользоваться менеджером контекста contextlib.redirect_stdout, который позволяет временно перенаправить stdout в любой объект, поддерживающий файловый интерфейс. В сочетании с io.StringIO это позволяет сохранить вывод в переменную.

from contextlib import redirect_stdout
from io import StringIO

s = StringIO()
with redirect_stdout(s):
    print(42)

print(s.getvalue())
Также существует contextlib.redirect_stderr для перенаправления вывода sys.stderr. 👉@BookPython

Погрузитесь в детство Не нужно ждать, чтобы подпевать Крокодилу Гене — включайте сборник аудиокниг Успенского в Звуке. Здесь Простоквашино, Чебурашка и другие Слушать #реклама 16+ open.zvuk.com О рекламодателе

Иногда в программе нужна очередь — контейнер, куда элементы добавляются с одной стороны и извлекаются с другой. В Python для этого можно использовать list:

In : lst = [1, 2, 3]
In : lst.pop()
Out: 3
In : lst
Out: [1, 2]
In : lst[:0] = [4]  # push
In : lst
Out: [4, 1, 2]
Однако list выглядит не очень удобно (взгляните на этот "push") и работает неэффективно.

In : lst = [0] * 10_000_000

In : %timeit lst[:0] = [1]
9.5 ms ± 111 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In : %timeit lst.pop()
84.3 ns ± 4.01 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Как видно, операция pop() в 100 раз быстрее, чем вставка в начало списка. Это связано с тем, как устроен list в Python: легко добавлять и удалять элементы с конца, но удаление/добавление в начало требует создания нового списка. Для очередей лучше использовать collections.deque. Он специально для этого создан:

In : from collections import deque
In : d = deque([1] * 100_000_000)
In : %timeit d.popleft()
65 ns ± 0.436 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
👉@BookPython

Скрытые фичи Enum: как выжать максимум Многие используют Enum как простой список констант. Но у enum.Enum в Python есть куда больше возможностей — и они могут сделать код чище и мощнее. Вот несколько приёмов, которые мало кто использует — но зря. 1. Добавление поведения в Enum

from enum import Enum

class Status(Enum):
    DRAFT = 'draft'
    PUBLISHED = 'published'
    ARCHIVED = 'archived'

    def is_visible(self):
        return self in {Status.DRAFT, Status.PUBLISHED}
Теперь Status.DRAFT.is_visible() — это просто и элегантно. 2. Enum с полями

from enum import Enum

class Color(Enum):
    RED = ('#FF0000', 'danger')
    GREEN = ('#00FF00', 'safe')

    def __init__(self, hex_code, label):
        self.hex_code = hex_code
        self.label = label

Color.RED.hex_code  # '#FF0000'
Color.RED.label     # 'danger'
3. Автоматические значения с auto()

from enum import Enum, auto

class Role(Enum):
    ADMIN = auto()
    USER = auto()
    GUEST = auto()
Удобно, если не важны конкретные значения, а нужны уникальные. 4. Строгая сериализация В реальных приложениях (API, базы) лучше контролировать сериализацию enum'ов:

import json

class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Enum):
            return obj.value
        return super().default(obj)

json.dumps(Status.PUBLISHED, cls=CustomEncoder)  # "published"
5. Сравнение по значению

Status('draft') == Status.DRAFT  # True
Status('draft') is Status.DRAFT  # True (enum гарантирует singleton)
Итого: Enum — это не просто константы. Это лёгкий способ инкапсулировать поведение и данные, улучшить читаемость и сделать код устойчивее к ошибкам. 👉@BookPython

Заработай на миграции инфраструктуры в облако Cloud4Y Предлагаем дополнительно заработать на своей ИТ-инфраструктуре. Партнёрская программа Cloud4Y позволяет сократить расходы компании, а вам заработать на этом как агенту. Переведите вашу текущую инфраструктуру в облако Cloud4Y, чтобы получить скидку до 25% на наши услуги от стоимости, указанной на сайте. А если вы уже используете облако другого провайдера, то, перейдя к нам, сможете сэкономить от 10% относительно текущей цены. За ваш переход мы готовы вознаградить вас лично: вы можете получать до 40% от ежемесячной стоимости потребляемых компанией облачных услуг. Это будет ваш регулярный пассивный доход. И помните: к этой акции применима наша акция по бесплатной миграции! Мы поможем вам перенести данные и приложения без лишних затрат и хлопот. Узнать больше #реклама 16+ cloud4y.ru О рекламодателе

Стандартный модуль json имеет интерфейс командной строки, который может быть полезен для форматирования JSON исключительно средствами Python. Модуль называется json.tool и вызывается следующим образом:

$ echo '{"a": [], "b": "c"}' | python -m json.tool
{
    "a": [],
    "b": "c"
}
👉@BookPython

Дарим подписку на Яндекс Музыку Ответьте на 1 вопрос и Яндекс Музыка ваша для вас и 3-х ваших близких. Кинопоиск и Яндекс Книги тоже в подписке. Попробуйте бесплатно❤️ Попробовать #реклама 18+ music.yandex.ru О рекламодателе Реклама на Яндексе

default_factory в dataclass: мощнее, чем кажется Многие используют dataclass как удобный способ задать структуру с полями. Но редко кто по-настоящему раскрывает силу default_factory. А зря — он спасает от багов и даёт гибкость. Когда нужно задать значение по умолчанию для поля в dataclass, логично тянуться к default=. Но если это изменяемый тип (например, список или словарь) — вас поджидает ловушка.

from dataclasses import dataclass, field

@dataclass
class User:
    name: str
    tags: list[str] = []  # ⚠️ опасно!
Все экземпляры User будут делить один и тот же список. То есть:

a = User("Alice")
b = User("Bob")
a.tags.append("admin")

print(b.tags)  # ['admin'] 😱
Вместо этого используйте default_factory:

@dataclass
class User:
    name: str
    tags: list[str] = field(default_factory=list)
Теперь у каждого User будет свой список:

a = User("Alice")
b = User("Bob")
a.tags.append("admin")

print(b.tags)  # []
Но default_factory не только про списки. Это отличный способ задать любое значение "по умолчанию", включая кастомную логику:

import uuid

@dataclass
class Session:
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
Или, например, значения из окружения:

import os

@dataclass
class Config:
    debug: bool = field(default_factory=lambda: os.getenv("DEBUG") == "1")
Кстати, это ещё и отличное место для внедрения DI:

@dataclass
class Service:
    client: "Client" = field(default_factory=create_default_client)
default_factory — это маленький хак, который позволяет сделать код чище и безопаснее, особенно когда работаешь с изменяемыми структурами или сложной инициализацией. 👉@BookPython

Запишитесь на бесплатную консультацию Уже более 15 лет мы создаем QA-отделы «с нуля» для IT-компаний. ✅Подбираем сильных спец
Запишитесь на бесплатную консультацию Уже более 15 лет мы создаем QA-отделы «с нуля» для IT-компаний. ✅Подбираем сильных специалистов. ✅Запускаем полный цикл тестирования. ✅Обучаем команду и внедряем прозрачные метрики оценки качества. Подумайте сами: выгоднее заплатить один раз, чтобы выстроить эффективный отдел тестировщиков, чем бесконечно наступать на одни и те же грабли, делая всё самостоятельно. Ведь если вы хотите автомобиль, то покупаете его, а не собираете самостоятельно. Так и с QA-отделом: зачем тратить время на то, что в «Лаборатории Качества» уже отточено до мелочей?! ⚡Давайте знакомиться! Уверены, что сможем быстро и профессионально решить вашу проблему. Первая консультация, анализ и оценка работ - бесплатно. Написать в Telegram #реклама quality-lab.ru О рекламодателе

yield from — элегантная передача управления Если вы пишете генераторы, которые вызывают другие генераторы — забудьте про for x in sub(): yield x. Есть способ проще и мощнее. Оператор yield from позволяет передавать элементы из подгенератора напрямую, без лишнего кода. Но фишка не только в лаконичности — он также автоматически пробрасывает исключения и возвращаемые значения из подгенератора. Вот классика:

def gen():
    for x in range(3):
        yield x

def wrapper():
    for x in gen():
        yield x
Можно короче и лучше:

def wrapper():
    yield from gen()
Но главное — yield from пробрасывает return-значение из подгенератора (начиная с Python 3.3):

def sub():
    yield 1
    yield 2
    return 'done'

def main():
    result = yield from sub()
    print('Sub returned:', result)

for _ in main():
    pass
# Выведет: Sub returned: done
А ещё через yield from можно проксировать значения внутрь генератора — например, в сопрограммах:

def delegator():
    result = yield from coroutine()
    print('coroutine done:', result)

def coroutine():
    x = yield
    y = yield
    return x + y

g = delegator()
next(g)          # Старт
next(g)          # coroutine ждет x
g.send(10)       # x = 10
print(g.send(20))  # y = 20 → return 30
# Выведет: coroutine done: 30
Итог: если вы пишете генераторы — освоение yield from даст вам лаконичный синтаксис, проброс return-значений, исключений и взаимодействие на новом уровне. 👉@BookPython

Python предоставляет мощную библиотеку для работы с датой и временем — datetime. Интересный момент: объекты datetime имеют специальный интерфейс для поддержки часовых поясов (атрибут tzinfo), однако сама библиотека `datetime реализует его лишь частично, оставляя остальную работу сторонним модулям. Самым популярным модулем для этой задачи является pytz. Хитрость в том, что pytz не полностью соответствует интерфейсу tzinfo. В документации pytz прямо указано с самого начала: «Эта библиотека отличается от задокументированного API Python для реализаций tzinfo». Вы не можете просто передать объект временной зоны pytz в атрибут tzinfo. Если попробуете, результат может быть абсолютно безумным:

In : paris = pytz.timezone('Europe/Paris')
In : str(datetime(2017, 1, 1, tzinfo=paris))
Out: '2017-01-01 00:00:00+00:09'
Посмотрите на этот смещение +00:09. Правильное использование pytz выглядит так:

In : str(paris.localize(datetime(2017, 1, 1)))
Out: '2017-01-01 00:00:00+01:00'
Кроме того, после любых операций с датой и временем, нужно нормализовать объект datetime, если есть вероятность смены смещения (например, на границе перехода на летнее время):

In : new_time = time + timedelta(days=2)
In : str(new_time)
Out: '2018-03-27 00:00:00+01:00'
In : str(paris.normalize(new_time))
Out: '2018-03-27 01:00:00+02:00'
Начиная с Python 3.6, рекомендуется использовать dateutil.tz вместо pytz. Он полностью совместим с tzinfo, может использоваться напрямую, не требует normalize, хотя и работает немного медленнее. Если вам интересно, почему pytz не поддерживает API datetime, или вы хотите увидеть больше примеров, обязательно почитайте хорошую статью на эту тему. 👉@BookPython

Когда вы используете модуль multiprocessing, и в одном из процессов происходит исключение, оно передаётся в основную программу с помощью механизма сериализации (pickling). Исключение сериализуется, передаётся в другой процесс и там десериализуется обратно. Однако сериализация исключений может быть непростой задачей. Исключение создаётся с любым количеством аргументов, которые сохраняются в атрибуте args. Эти же аргументы используются при десериализации для воссоздания объекта исключения. Но это может не сработать так, как вы ожидаете, особенно если используется наследование. Посмотрите на пример:

import pickle

class TooMuchWeightError(Exception):
    def __init__(self, weight):
        super().__init__()
        self._weight = weight

pickled = pickle.dumps(TooMuchWeightError(42))
pickle.loads(pickled)
Вызов TooMuchWeightError.__init__ приводит к вызову Exception.__init__, который устанавливает args как пустой кортеж. Этот пустой кортеж затем используется в качестве аргументов при десериализации, что, очевидно, приводит к ошибке:
TypeError: __init__() missing 1 required positional argument: 'weight'
Обходное решение — либо вообще не вызывать super().__init__() (что обычно считается плохой практикой при наследовании), либо передавать все аргументы явно в конструктор родительского класса:

class TooMuchWeightError(Exception):
    def __init__(self, weight):
        super().__init__(weight)
        self._weight = weight
👉@BookPython

Лямбды в Python не могут делать многое из того, что умеют обычные функции. В теле лямбда-выражения можно использовать только одно выражение, нельзя писать операторы (такие как a = b, yield, await и т.д.), также нельзя добавлять аннотации типов или объявлять лямбду как async. Тем не менее, если очень нужно превратить лямбду в асинхронную функцию, можно использовать декоратор asyncio.coroutine. Это было полезно до появления ключевого слова async в Python 3.4, но в современном Python почти не применяется.

>>> f = asyncio.coroutine(lambda x: x ** 2)
>>> asyncio.get_event_loop().run_until_complete(f(12))
144
Разумеется, это всё равно не позволяет использовать await внутри лямбды. 👉@BookPython