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

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

前往频道在 Telegram

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

显示更多

📈 Telegram 频道 Библиотека Python разработчика | Книги по питону 的分析概览

频道 Библиотека Python разработчика | Книги по питону (@bookpython) 俄语 语言赛道中的 是活跃参与者。目前社区聚集了 18 329 名订阅者,在 技术与应用 类别中位列第 7 307,并在 俄罗斯 地区排名第 36 869

📊 受众指标与增长动态

невідомо 创建以来,项目保持高速增长,吸引了 18 329 名订阅者。

根据 04 六月, 2026 的最新数据,频道保持稳定运转。过去 30 天订阅人数变化为 -86,过去 24 小时变化为 -1,整体触达仍然可观。

  • 认证状态: 未认证
  • 互动率 (ER): 平均受众互动率为 6.07%。内容发布后 24 小时内通常能获得 2.61% 的反应,占订阅者总量。
  • 帖子覆盖: 每篇帖子平均可获得 1 112 次浏览,首日通常累积 479 次浏览。
  • 互动与反馈: 受众积极参与,单帖平均反应数为 2
  • 主题关注点: 内容集中在 numbers, yield, модуль, none, декоратор 等核心主题上。

📝 描述与内容策略

作者将该频道定位为表达主观观点的平台:
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq

凭借高频更新(最新数据采集于 05 六月, 2026),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。

18 329
订阅者
-124 小时
-297
-8630
帖子存档
Рассмотрим следующую иерархию классов:

class GrandParent:
    pass

class Parent1(GrandParent):
    pass

class Parent2(GrandParent):
    pass

class Child(Parent1, Parent2):
    pass
В каком порядке будет производиться поиск метода Child.x()? Наивный подход заключается в рекурсивном поиске через все родительские классы, что даст порядок: Child, Parent1, GrandParent, Parent2. Такой метод используется во многих языках программирования, однако он не совсем логичен, так как Parent2 более специфичен, чем GrandParent, и его нужно проверять раньше. Чтобы исправить эту проблему, Python использует линеаризацию C3 (C3 superclass linearization), алгоритм, который всегда ищет метод сначала во всех дочерних классах, а затем уже в родительских. Пример вывода MRO (Method Resolution Order):

In : Child.__mro__
Out:
(__main__.Child,
 __main__.Parent1,
 __main__.Parent2,
 __main__.GrandParent,
 object)
📲 Мы в MAX 👉@BookPython

Финансовая грамотность — не про ограничения. Необязательно отказываться от латте. Важно понимать, что это, например, ₽5 000 в
Финансовая грамотность — не про ограничения. Необязательно отказываться от латте. Важно понимать, что это, например, ₽5 000 в месяц, и делать это осмысленно. ✅ФинКод — канал и чат-бот — рассказывает, как принимать осознанные финансовые решения и подбирать инструменты для грамотного управления финансами. В жизни важен баланс, а не экономический марафон. Так появляется стабильность без аскетизма. И да, кофе остаётся. Только теперь без чувства вины. Подписаться #реклама 16+ О рекламодателе

Когда корутина asyncio хочет остановиться и взаимодействовать с циклом событий (event loop), она использует await obj (или yield from obj до Python 3.6). Объект obj должен быть другой корутиной, объектом asyncio.Future или любым пользовательским объектом, похожим на Future (любой объект, у которого определен метод __await__).

async def coroutine():
    await another_coroutine()

async def another_coroutine():
    future = asyncio.Future()
    await future

loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
Когда корутина ожидает (await) другую корутину, вторая начинает выполняться вместо первой. Если она ожидает третью, то выполняется третья. Это продолжается до тех пор, пока какая-нибудь корутина не ожидает объект Future. Объект Future фактически возвращает значение, и тогда цикл событий (event loop) получает управление. Какое значение возвращает Future? Оно возвращает сам себя. Можете ли вы напрямую использовать yield для Future? Нет, это внутренняя деталь, о которой вам обычно не нужно беспокоиться.

class Awaitable:
    def __await__(self):
        future = asyncio.Future()
        yield future
            # RuntimeError: yield was used
            # instead of yield from in task

async def coroutine():
    await Awaitable()

loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine())
Почему возникает эта ошибка? Как asyncio понимает, что это вы используете yield для Future, а не сам Future? Есть простая защита: Future устанавливает внутренний флаг перед тем, как вернуть управление. 📲 Мы в MAX 👉@BookPython

Иногда вам нужно запустить блок кода с несколькими контекстными менеджерами. Например:

with open('f') as f:
    with open('g') as g:
        with open('h') as h:
            pass
Начиная с Python 2.7 и 3.1, это можно сделать с помощью одного выражения with:

o = open
with o('f') as f, o('g') as g, o('h') as h:
    pass
До этого можно было использовать функцию contextlib.nested:

with nested(o('f'), o('g'), o('h')) as (f, g, h):
    pass
Однако в современных версиях Python эта функция устарела и вызывает предупреждение. Вместо неё рекомендуется использовать более продвинутый инструмент — contextlib.ExitStack. Он позволяет войти в любое количество контекстов в произвольное время, но гарантирует их корректное завершение:

from contextlib import ExitStack

with ExitStack() as stack:
    f = stack.enter_context(o('f'))
    g = stack.enter_context(o('g'))
    other = [
        stack.enter_context(o(filename))
        for filename in filenames
    ]
Это особенно полезно, когда количество контекстных менеджеров неизвестно заранее. 📲 Мы в MAX 👉@BookPython

Знаете ли вы, как вейпы влияют на здоровье? В канале разберем мифы о новой привычке. Узнайте, как обыденные, на первый взгляд
Знаете ли вы, как вейпы влияют на здоровье? В канале разберем мифы о новой привычке. Узнайте, как обыденные, на первый взгляд вещи, сказываются на здоровье сердца в частности, и общем благополучии организма в целом. Наши эксперты делятся только полезными и доказанными фактами из мира медицины. Подписывайтесь на наш канал «Если у вас есть сердце» и следите за последними новостями о здоровом образе жизни! Подробнее #реклама О рекламодателе

UTF-8 - это кодировка с переменной длиной. Один символ может быть закодирован с использованием одного, двух, трёх или четырёх байтов. Это означает, что нельзя начать чтение строки в кодировке UTF-8 с произвольного байта, так как это может случайно разрушить символ:

In : lion = 'Löwe'
In : lion.encode('utf-8')[2:]
Out: b'\xb6we'
In : lion.encode('utf-8')[2:].decode('utf-8')
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb6 in position 0: invalid start byte
Также это означает, что для пропуска первых N символов строки их необходимо прочитать и декодировать. Рассчитать смещение заранее невозможно. Однако можно пропустить фиксированное количество байтов, принимая во внимание некоторые особенности. Вот как может быть закодирован символ в UTF-8:

0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Как видно, байт является начальным байтом символа, если его вид не совпадает с 10xxxxxx. Такие байты называются продолжением символа (continuation bytes). Давайте пропустим их:

def cut_bytes(s, n):
    result = s.encode('utf-8')[n:]
    mask = int('11000000', 2)
    conbyte = int('10000000', 2)
    while result[0] and result[0] & mask == conbyte:
        result = result[1:]

    return result.decode('utf-8')
Пример использования:

In : cut_bytes(lion, 2)
Out: 'we'
In : cut_bytes(lion, 1)
Out: 'öwe'
📲 Мы в MAX 👉@BookPython

Нативные значения float в Python используют аппаратные возможности вашего компьютера, поэтому любое значение внутренне представлено в виде двоичной дроби. Это означает, что в большинстве случаев вы работаете с приближениями, а не с точными значениями:

In : format(0.1, '.17f')
Out: '0.10000000000000001'
Модуль decimal позволяет использовать десятичную арифметику с произвольной точностью:

In : Decimal(1) / Decimal(3)
Out: Decimal('0.3333333333333333333333333333')
Однако и этого может быть недостаточно:

In [61]: Decimal(1) / Decimal(3) * Decimal(3) == Decimal(1)
Out[61]: False
Для точных вычислений можно использовать fractions, где любое число хранится в виде рационального:

In : Fraction(1) / Fraction(3) * Fraction(3) == Fraction(1)
Out: True
Очевидным ограничением остается то, что иррациональные числа (например, π) все равно будут представлены только в приближенной форме. 📲 Мы в MAX 👉@BookPython

Реклама для бизнеса любого уровня в Яндекс Директе Создайте эффективную рекламную кампанию с алгоритмами Яндекс Директа 👌 На
Реклама для бизнеса любого уровня в Яндекс Директе Создайте эффективную рекламную кампанию с алгоритмами Яндекс Директа 👌 Начните прямо сейчас ⚡ Зарегистрироваться #реклама direct.yandex.ru О рекламодателе

Тесты могут требовать временные файлы или директории. Для этого отлично подойдет модуль tempfile. Так как временные файлы обычно нужно удалять после использования, tempfile предоставляет как контекстный менеджер, так и простые функции:

import os
import tempfile

with tempfile.TemporaryDirectory() as dir_path:
    open(os.path.join(dir_path, 'a'), 'w').close()
    open(os.path.join(dir_path, 'b'), 'w').close()
    open(os.path.join(dir_path, 'c'), 'w').close()

    assert files_of(dir_path) == ['a', 'b', 'c']
📲 Мы в MAX 👉@BookPython

Продвижение в Telegram с помощью Яндекс Директа ⚡Запустите продвижение в телеграм-каналах и привлекайте целевую аудиторию 📱
+3
Продвижение в Telegram с помощью Яндекс Директа ⚡Запустите продвижение в телеграм-каналах и привлекайте целевую аудиторию 📱 Таргетинг по тематикам, регионам и каналам в Telegram Попробовать #реклама yandex.ru О рекламодателе

Когда вы создаете кастомный метод __repr__ для объекта, обычно нужно включить представление его атрибутов. Однако важно помнить, что нужно явно вызывать repr(), так как форматирование вызывает str() вместо repr(). Пример простого кода:

class Pair:
    def __init__(self, left, right):
        self.left = left
        self.right = right
        
    def __repr__(self):
        class_name = type(self).__name__
        repr_left = repr(self.left)
        repr_right = repr(self.right)
        return f'{class_name}({repr_left}, {repr_right})'
Проблема возникает, если вы вызываете repr для объекта, который содержит ссылку на самого себя. Это может привести к рекурсии:

In : p = Pair(1, 2)
In : p
Out: Pair(1, 2)
In : p.right = p
In : p
Out: [...]
RecursionError: maximum recursion depth exceeded while calling a Python object
Для решения этой проблемы можно использовать декоратор reprlib.recursive_repr, который обрабатывает рекурсивные вызовы:

@reprlib.recursive_repr()
def __repr__(self):
    class_name = type(self).__name__
    repr_left = repr(self.left)
    repr_right = repr(self.right)
    return f'{class_name}({repr_left}, {repr_right})'
Теперь код работает корректно:

In : p = Pair(1, 2)
In : p.right = p
In : p
Out: Pair(1, ...)
📲 Мы в MAX 👉@BookPython

27 ноября собираемся на Pytup: митап Яндекса для Python-разработчиков и ML-инженеров 🚀 Присоединяйтесь в Екатеринбурге или о
27 ноября собираемся на Pytup: митап Яндекса для Python-разработчиков и ML-инженеров 🚀 Присоединяйтесь в Екатеринбурге или онлайн, чтобы в неформальной обстановке поговорить о Python, машинном обучении и технологиях, которые двигают индустрию вперед. В программе выступлений: > Арсений Саблин, разработчик системы контроля качества умных устройств на производстве (Яндекс Алиса), поделится, как используется Python при тестировании станции с Алисой; > Никита Улько, техлид VK Tech, разберет чистую архитектуру с практической точки зрения: за что ее ценят и как гибко применять ее принципы, фокусируясь на решении конкретных проблем; > Егор Гордовский, технический менеджер проектов Yandex Cloud, расскажет о сложном техническом организме, помогающем превратить код в работающий сервис — дата-центре. Помимо докладов участников в Екатеринбурге ждет дискуссия Snake Pit, а также соревнования по классической «Змейке» и гонки на игрушечных роботах-доставщиках. 📅 27 ноября в 17.00 (по Екб) 📍 Екатеринбург (креативный кластер «Домна») + онлайн Регистрация на митап

В Python блок else можно использовать не только после if, но и после циклов for и while. Код внутри else выполняется только в том случае, если цикл завершился естественным образом, то есть не был прерван с помощью break. Наиболее распространённый случай использования этого — поиск элемента в цикле с прерыванием через break, если элемент найден:

# Пример 1: Список содержит нечётное число
first_odd = None
for x in [2, 3, 4, 5]:
    if x % 2 == 1:  # Проверяем, является ли число нечётным
        first_odd = x
        break       # Прерываем цикл, так как элемент найден
else:
    raise ValueError('No odd elements in list')  # Выполнится, если цикл завершился без break

print(first_odd)  # Результат: 3
Если в списке нет подходящего элемента, цикл завершается естественным образом, и выполняется блок else:

# Пример 2: Список не содержит нечётных чисел
for x in [2, 4, 6]:
    if x % 2 == 1:
        first_odd = x
        break
else:
    raise ValueError('No odd elements in list')  # Исключение будет поднято

# ValueError: No odd elements in list
📲 Мы в MAX 👉@BookPython

Видовые квартиры в Ялте с собственным пляжем ЖК "Юсуповский" — ваша личная резиденция бизнес-класса на берегу моря! Здесь каж
Видовые квартиры в Ялте с собственным пляжем ЖК "Юсуповский" — ваша личная резиденция бизнес-класса на берегу моря! Здесь каждый элемент говорит о статусе: от величественного фасада до 2-этажного SPA и фитнес-центра на территории. ✅ Панорамное остекление ✅ Открытый подогреваемый бассейн и закрытый двор-парк 2 га ✅ 2-этажные квартиры ✅ Трансфер к пляжу ✅ Реликтовый парк и водопад на территории. Всего в нескольких минутах езды: Ливадийский дворец, Солнечная тропа, ведущая вдоль побережья, а также лучшие рестораны и культурные, развлекательные объекты Ялты. Это инвестиция в будущее: Ваш второй дом и источник вдохновения для будущих поколений. До 30 ноября 2025 года вы можете купить квартиры в рассрочку 0%. Не упустите эту возможность! Купить Проектная декларация на сайте https://наш.дом.рф/. Застройщик: ООО СЗ ВОЛГА. Финансовые услуги оказывает: ПАО "Сбербанк". #реклама gk-yusupovskiy.ru О рекламодателе

Функция itertools.chain позволяет объединить несколько итерируемых объектов, чтобы работать с ними, как с единым целым:

from itertools import chain

print(list(chain(['a', 'b'], range(3), set('xyz'))))
# Вывод: ['a', 'b', 0, 1, 2, 'x', 'z', 'y']
Иногда нужно проверить, пуст ли генератор (точнее, исчерпан ли он). Для этого можно попытаться получить следующий элемент с помощью next(). Если элемент есть, его нужно вернуть обратно в генератор, но сделать это напрямую невозможно. Однако можно «приклеить» его обратно с помощью chain:

from itertools import chain

def sum_of_odd(gen):
    try:
        first = next(gen)  # Пытаемся получить первый элемент
    except StopIteration:
        raise ValueError('Empty generator')  # Если генератор пуст, выбрасываем исключение

    # Используем chain для возврата первого элемента и объединения с остальными
    return sum(
        x for x in chain([first], gen)
        if x % 2 == 1  # Суммируем только нечетные числа
    )
Пример использования:

print(sum_of_odd(x for x in range(1, 6)))  # Вывод: 9 (1 + 3 + 5)
print(sum_of_odd(x for x in range(2, 3)))  # Вывод: 0 (нет нечетных чисел)
print(sum_of_odd(x for x in range(2, 2)))  # ValueError: Empty generator
📲 Мы в MAX 👉@BookPython

Методичка: как сделать онлайн-встречи эффективнее Надоело ждать коллег, которые постоянно забывают о встречах, а отсутствие п
Методичка: как сделать онлайн-встречи эффективнее Надоело ждать коллег, которые постоянно забывают о встречах, а отсутствие повестки и потерянные договоренности мешают нормально работать? Команда МТС Линк собрала на 37 страницах полезные материалы, чек-листы и кейсы, которые помогают компаниям проводить эффективные совещания в онлайне с помощью сервиса Встречи. Из методички узнаете: - Как создать постоянную ссылку и подключаться на встречи в 2 клика, - Как делать заметки и работать с файлами, не переживая за качество связи и безопасность данных. - Как облегчает жизнь ИИ, который расшифровывает созвоны в текст и автоматически отправляет расшифровку на почту. Еще в методичке описаны 7 способов оценки текущей эффективности ваших онлайн-встреч. Получить гайд можно бесплатно на сайте. Скачать #реклама 16+ mts-link.ru О рекламодателе

Метод format в Python для строк — мощный инструмент, поддерживающий множество возможностей, о которых вы, возможно, даже не знали. Каждый заменяемый плейсхолдер ({...}) может содержать три части: имя поля, преобразование и спецификацию формата. Имя поля используется для указания, какой именно аргумент должен быть подставлен:

>>> '{}'.format(42)
'42'
>>> '{1}'.format(1, 2)
'2'
>>> '{y}'.format(x=1, y=2)
'2'
Преобразование позволяет указать, что вместо str() следует использовать repr() (или ascii()) при преобразовании объектов в строки:

>>> '{!r}'.format(datetime.now())
'datetime.datetime(2018, 5, 3, 23, 48, 49, 157037)'
>>> '{}'.format(datetime.now())
'2018-05-03 23:49:01.060852'
Спецификация формата задаёт, как значения будут представлены:

>>> '{:+,}'.format(1234567)
'+1,234,567'
>>> '{:>19}'.format(1234567)
'            1234567'
Эта спецификация может быть применена и к отдельному объекту с помощью функции format (не метода str):

>>> format(5000000, '+,')
'+5,000,000'
Функция format вызывает метод __format__ объекта, поэтому вы можете изменить его поведение для своих типов. 📲 Мы в MAX 👉@BookPython

Запустите рекламу в телеграм-каналах с Яндекс Директом Перфоманс-реклама теперь в телеграм-каналах ⚡ Яндекс Директ знает, как
Запустите рекламу в телеграм-каналах с Яндекс Директом Перфоманс-реклама теперь в телеграм-каналах ⚡ Яндекс Директ знает, как привлечь целевую аудиторию 💰👌 Попробовать #реклама yandex.ru О рекламодателе

Иногда нужно создать функцию на основе более универсальной. Например, у функции int() есть параметр base, который можно зафиксировать, чтобы получить новую функцию base2:

>>> int("10")
10
>>> int("10", 2)
2
>>> def base2(x):
...     return int(x, 2)
...
>>> base2("10")
2
Для более точной и семантически понятной реализации можно использовать functools.partial:

from functools import partial

base2 = partial(int, base=2)
Это удобно, когда нужно передать функцию в качестве аргумента в другую функцию высшего порядка, но с заблокированными значениями некоторых аргументов:

>>> list(map(partial(int, base=2), ["1", "10", "100"]))
[1, 2, 4]
Без использования partial пришлось бы писать код так:

>>> list(map(lambda x: int(x, base=2), ["1", "10", "100"]))
[1, 2, 4]
📲 Мы в MAX 👉@BookPython

S7 Airlines Комфортный полет. Выбирайте билеты на сайте Перейти на сайт #реклама nebo.s7.ru О рекламодателе
S7 Airlines Комфортный полет. Выбирайте билеты на сайте Перейти на сайт #реклама nebo.s7.ru О рекламодателе