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

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

前往频道在 Telegram

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

显示更多

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

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

📊 受众指标与增长动态

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

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

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

📝 描述与内容策略

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

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

18 321
订阅者
-124 小时
-277
-8630
帖子存档
Нативные значения 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
Очевидным ограничением остается то, что иррациональные числа (например, π) все равно будут представлены только в приближенной форме. 👉@BookPython

Тесты могут требовать временные файлы или директории. Для этого отлично подойдет модуль 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']
👉@BookPython

Концептуальные офисы в БЦ RUNOVSKY 14 Бизнес-центр «RUNOVSKY 14» предлагает премиальный сервис и разнообразие планировочных р
Концептуальные офисы в БЦ RUNOVSKY 14 Бизнес-центр «RUNOVSKY 14» предлагает премиальный сервис и разнообразие планировочных решений - лоты с площадью от 27 м² с возможностью объединения смежных помещений и высотой потолков 3,2 м. Почему выбирают нас? Расположение: всего 6 минут от Кремля! Панорамное остекление: дает ощущение простора, обилие солнечного света и воздуха. Рестораны и переговорные: всё необходимое для вашего удобства на территории. Интеллектуальный климат: создаёт комфортные условия для продуктивной работы. Консьерж-сервис: администратор всегда поможет встретить гостей, принять посылку или заказать машину. Не упустите возможность стать частью этого уникального пространства! Перейти на сайт #реклама зиккурат.рф О рекламодателе

Чтобы читать строки из stdin в Python до версии 3, использовалась функция raw_input вместо input. Проблема с использованием input заключалась в том, что она выполняла введённую строку как код:

$ echo '[x ** 2 for x in range(10)]' | python2 -c 'print input()'
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
В Python 3 функция input просто читает строку, а raw_input больше не существует. Если вы хотите поддерживать код, работающий как в Python 2, так и в Python 3, можно использовать следующий подход:

from contextlib import suppress

with suppress(NameError):
    input = raw_input
Популярный модуль six уже реализует этот механизм для вас. Он предоставляет функцию input, которая просто читает строку, независимо от версии Python. 👉@BookPython

Неделя выгодных цен на 1-комнатные квартиры в Краснодаре «Родные Просторы» - микрорайон площадью 41,3 га для тех, кому важно
Неделя выгодных цен на 1-комнатные квартиры в Краснодаре «Родные Просторы» - микрорайон площадью 41,3 га для тех, кому важно иметь поблизости необходимые объекты инфраструктуры и комфортную среду для жизни: - квартиры с продуманными планировками - детские площадки, парковая зона, спортивные площадки - магазины, школа, детские сады, поликлиники - видеонаблюдение и система антиобледенения - доступные цены и выгодные условия покупки ✅Платеж по ипотеке от 28 467 руб/месРассрочка без удорожания до конца строительства с первоначальным взносом от 30% ✅ПСК 23,157-30,233%. Семейная ипотека от 6% ЖК "Родные Просторы" - это ваш идеальный выбор! Узнать цену Проектная декларация на сайте https://наш.дом.рф/. Застройщик: ООО СЗ ЮГСТРОЙИМПЕРИАЛ. Финансовые услуги оказывает: ПАО "Сбербанк", АО "АЛЬФА-БАНК" и др.. #реклама promo.tochno-rp.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, ...)
👉@BookPython

Сочи, 25м² с ремонтом, вид на море, цена снижена на 21% На территории круглогодичный бассейн, рестораны, детские и спорт площадки. 7 минут пешком до пляжа. Надежный застройщик. ⚡ Квартиры в ЖК доступны в : ✅ субсидированную ипотеку под 0,1% (возможна программа без первоначального взноса) ✅ беспроцентную рассрочку. Оставь телефон чтобы узнать цену! Смотреть Финансовые услуги оказывает: АО "Альфа Банк", АО "Россельхозбанк" и др.. #реклама mrqz.me О рекламодателе

В 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
👉@BookPython

Квартиры в Краснодаре от 3,3 млн. руб. Новый жилой район "Первое место" в Краснодаре. Здесь всё для счастливой жизни на перво
Квартиры в Краснодаре от 3,3 млн. руб. Новый жилой район "Первое место" в Краснодаре. Здесь всё для счастливой жизни на первом месте: - Две школы - Шесть детских садов - Поликлиники - Собственный фитнес-центр - Многоуровневый паркинг Жилой комплекс располагается в новом районе города «Новознаменский», в Карасунском округе Краснодара и имеет удобный выезд на трассу М4 ДОН, Джубгскую трассу в направлении Черного моря и горнолыжных курортов. Только в декабре скидка 8% при покупке квартиры за собственные средства. Успейте забрать билет в жизнь, где вы всегда будете на «Первом месте»! Получить предложение Проектная декларация на сайте https://наш.дом.рф/. Застройщик: ООО " СЗ Живые квартиры" #реклама promo.tochno-pervoe.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
👉@BookPython

Дарим подписку на Яндекс Музыку Ответьте на 1 вопрос и Яндекс Музыка для вас и 3-х ваших близких 30 дней бесплатно. Кинопоиск
Дарим подписку на Яндекс Музыку Ответьте на 1 вопрос и Яндекс Музыка для вас и 3-х ваших близких 30 дней бесплатно. Кинопоиск и Яндекс Книги тоже в подписке. Попробуйте сейчас❤️ Попробовать #реклама 18+ music.yandex.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__ объекта, поэтому вы можете изменить его поведение для своих типов. 👉@BookPython

Визуализация данных — это ключевой этап анализа, который помогает выявить скрытые закономерности, а также улучшить понимание
Визуализация данных — это ключевой этап анализа, который помогает выявить скрытые закономерности, а также улучшить понимание структуры данных для дальнейшего применения машинного обучения Приглашаем на открытый урок «Визуализация данных на Python», посвященный курсу «Machine Learning» от Otus. ✅ Практика: визуализация данных Python на основных библиотеках: Matplotlib; Seaborn; Plotly 👉 Регистрация и подробности: https://vk.cc/cH48zk Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.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]
👉@BookPython

🔑 Использование объектов в качестве ключей словаря в Python В Python вы можете использовать любой объект в качестве ключа словаря, если он реализует метод __hash__. Этот метод возвращает целое число, но при этом важно соблюдать одно ключевое требование: равные объекты должны иметь одинаковый хэш (обратное утверждение необязательно). 👉 Не используйте изменяемые объекты в качестве ключей! Если объект изменяется после добавления в словарь, он становится "невидимым" для поиска, так как его хэш может измениться. 🌀 Странность с отрицательными хэшами Есть интересная особенность, которая может вас удивить при отладке или написании юнит-тестов. Рассмотрим следующий пример:

class A:
    def __init__(self, x):
        self.x = x

    def __hash__(self):
        return self.x
Результаты хэширования экземпляров класса:

>>> hash(A(2))
2
>>> hash(A(1))
1
>>> hash(A(0))
0
>>> hash(A(-1))  # внимание!
-2
>>> hash(A(-2))
-2
💡 В CPython значение -1 зарезервировано для внутренних ошибок. Если хэш-значение равно -1, интерпретатор автоматически преобразует его в -2. Это может вызывать неожиданные проблемы при сравнении или использовании объектов в качестве ключей. 👉 @BookPython

Hermes: мужские зимние кроссовки с мехом ⚡ Онлайн-магазин брендовой одежды, обуви и аксессуаров по самым выгодным ценам! ✅ Ты
+4
Hermes: мужские зимние кроссовки с мехом ⚡ Онлайн-магазин брендовой одежды, обуви и аксессуаров по самым выгодным ценам! ✅ Тысячи моделей от топовых брендов, премиум качество, новинки каждый день! Tommy Hilfiger Burberry Emporio Armani 7 Moncler Dolce & Gabbana Hugo Boss Polo Ralph Lauren Hermes Brunello Cucinelli и др. 🚗 Доставка с примеркой по Москве, быстрая доставка по всей России и СНГ. 💰 Скидки до -80% в нашем дисконт Telegram-канале. ❤️ Твой новый стиль всего в одном клике. Переходи! Подписаться #реклама О рекламодателе

📌 О представлении данных в байтах в Python Когда мы храним данные в памяти или на устройстве хранения, их необходимо представить в виде байтов. Python позволяет работать с абстракцией данных, не задумываясь об их байтовом представлении. Однако при записи строки в файл мы фактически работаем с физической структурой данных. Чтобы записать символы в файл, их нужно преобразовать в байты — это называется кодированием (encoding). Когда вы читаете байты из файла и хотите преобразовать их в понятные символы, этот процесс называется декодированием (decoding). 🔤 Кодировки и их применение Существует множество методов кодирования. Один из самых популярных — Unicode, но сам по себе Unicode не является кодировкой в традиционном смысле. Unicode определяет соответствие между символами и их числовыми кодами. Например, 🐍 имеет код 128 013. Однако, чтобы записать числа в файл, нужна настоящая кодировка. Unicode обычно используется с utf-8, которая (в большинстве случаев) является кодировкой по умолчанию в Python. При чтении из файла Python автоматически декодирует данные, используя utf-8. Если вы хотите использовать другую кодировку, просто укажите её с помощью параметра encoding= в функции open. А чтобы работать с "чистыми" байтами, добавьте символ b к режиму открытия файла. Пример:

# Кодирование строки в файл
with open('example.txt', 'w', encoding='utf-8') as f:
    f.write('Привет, мир!')

# Чтение в байтовом режиме
with open('example.txt', 'rb') as f:
    data = f.read()
    print(data)  # Вывод: b'\xd0\x9f\xd1\x80\xd0\xb8...'
👉 @BookPython

Студия в Краснодаре за 16 780 р/мес. МКР Родные просторы Жилой комплекс "Родные Просторы" в Краснодаре - это масштабный проек
Студия в Краснодаре за 16 780 р/мес. МКР Родные просторы Жилой комплекс "Родные Просторы" в Краснодаре - это масштабный проект группы компаний ТОЧНО, который предлагает уникальные условия для комфортной жизни. "Родные просторы" - это не просто квартиры, это целый микрорайон, созданный с учетом потребностей современных семей. Здесь предусмотрены разнообразные планировки и высококачественная отделка, что позволяет каждому выбрать идеальное жильё. ✨Уникальное предложение этого месяца - студия за 16 780 рублей в месяц. Узнать больше Проектная декларация на сайте https://наш.дом.рф/. Застройщик: ООО СЗ ЮГСТРОЙИМПЕРИАЛ. Финансовые услуги оказывает: ПАО "Сбербанк", АО "АЛЬФА-БАНК" и др.. #реклама promo.tochno-rp.ru О рекламодателе

Если вам нужно выполнить поиск в отсортированной коллекции, то бинарный поиск — это именно то, что вам нужно. Этот простой алгоритм сравнивает искомое значение с элементом в середине массива; результат определяет, какую половину нужно искать дальше. Стандартная библиотека Python предоставляет возможность использовать бинарный поиск без его непосредственной реализации. Функция bisect_left возвращает самую левую позицию элемента в отсортированном списке, а bisect_right — самую правую.

from random import randrange
from bisect import bisect_left

n = 1000000
look_for = 555555
lst = sorted(randrange(0, n) for _ in range(n))

%timeit look_for in lst
# 69.7 ms ± 449 µs на цикл

%timeit look_for == lst[bisect_left(lst, look_for)]
# 927 ns ± 2.28 ns на цикл
Результаты демонстрируют, что использование бинарного поиска через bisect_left быстрее, чем стандартный поиск в списке с помощью оператора in. 👉 @BookPython

Модуль multiprocessing в Python: потоки против процессов Модуль multiprocessing позволяет создавать не только процессы, но и потоки. Однако стоит помнить о главной особенности CPython — GIL (Global Interpreter Lock). Этот механизм блокирует выполнение байт-кода Python несколькими потоками одновременно. Это означает, что потоки полезны в основном в случаях, когда программа выполняет операции, не связанные с Python-интерпретатором, например, ожидание ввода-вывода (IO). К примеру, загрузка трёх различных статей из Википедии будет одинаково эффективной как с потоками, так и с процессами. Причём результат в три раза быстрее по сравнению с выполнением задачи в одном процессе:

from multiprocessing import Pool
from multiprocessing.pool import ThreadPool
import requests

def download_wiki_article(article):
    url = 'http://de.wikipedia.org/wiki/'
    return requests.get(url + article)

process_pool = Pool(3)
thread_pool = ThreadPool(3)

thread_pool.map(download_wiki_article, ['a', 'b', 'c'])
# ~376 ms

process_pool.map(download_wiki_article, ['a', 'b', 'c'])
# ~373 ms

[download_wiki_article(a) for a in ['a', 'b', 'c']]
# ~1.09 s
Однако использование потоков для задач, нагружающих CPU, практически бессмысленно:

import math
from multiprocessing import Pool
from multiprocessing.pool import ThreadPool

def f(x):
    return len(str(math.factorial(x)))

process_pool = Pool(4)
thread_pool = ThreadPool(4)
inputs = [i ** 2 for i in range(100, 130)]

[f(x) for x in inputs]
# ~1.48 s

thread_pool.map(f, inputs)
# ~1.48 s

process_pool.map(f, inputs)
# ~478 ms
При задачах, требующих интенсивных вычислений, использование процессов вместо потоков даст значительный прирост производительности благодаря распределению нагрузки между несколькими ядрами процессора. 👉 @BookPython