Библиотека Python разработчика | Книги по питону
Погружение в 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 329 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 329 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.
from contextlib import contextmanager
QUIT_MESSAGE = 'Bye'
def print_quit_mesage():
global QUIT_MESSAGE
print(QUIT_MESSAGE)
@contextmanager
def global_variable_changed(name, value):
orig_value = globals()[name]
globals()[name] = value
yield
globals()[name] = orig_value
with global_variable_changed(
'QUIT_MESSAGE',
'Tschüss'
):
print_quit_mesage()
👉@BookPython
class Task:
_task_id = 0
def __init__(self):
self._id = self._task_id
type(self)._task_id += 1
Обрати внимание, что нельзя использовать self._task_id += 1 — это создаст атрибут _task_id внутри экземпляра, а не изменит значение на уровне класса.
Лучше использовать фабричный метод вместо __init__, чтобы код выглядел аккуратнее:
class Task:
_task_id = 0
def __init__(self, task_id):
self._id = task_id
@classmethod
def create(cls):
obj = cls(cls._task_id)
cls._task_id += 1
return obj
Эта версия также проще для тестирования, так как можно легко задать любой ID вручную.
👉@BookPythonfor. Это all и any.
any возвращает True, если хотя бы одно значение истинно; all возвращает True, только если все значения истинны. Для пустого итерируемого объекта all возвращает True, а any — False.
Обе функции особенно полезны в сочетании со списковыми включениями (list comprehensions):
package_broken = any(
part.is_broken() for part in package.get_parts()
)
package_ok = all(
part.ok() for part in package.get_parts()
)
Функции any и all зачастую взаимозаменяемы благодаря законам де Моргана. Используй ту, с которой код будет понятнее.
👉@BookPythonint() есть параметр base, который мы хотим зафиксировать, чтобы получить новую функцию base2:
>>> int("10")
10
>>> int("10", 2)
2
>>> def base2(x):
... return int(x, 2)
...
>>> base2("10")
2
functools.partial позволяет сделать то же самое, но точнее и семантически понятнее:
base2 = partial(int, base=2)
Это полезно, когда нужно передать функцию как аргумент другой, более общей функции, но при этом некоторые аргументы должны быть зафиксированы:
>>> map(partial(int, base=2), ["1", "10", "100"])
[1, 2, 4]
Без partial пришлось бы делать так:
>>> map(lambda x: int(x, base=2), ["1", "10", "100"])
[1, 2, 4]
👉@BookPythonloop.run_in_executor.
Сторонний модуль aiofiles делает всё это за тебя, предоставляя простой и удобный интерфейс:
async with aiofiles.open('filename', mode='r') as f:
contents = await f.read()
👉@BookPython>>> bool(datetime(2018, 1, 1).time())
False
>>> bool(datetime(2018, 1, 1, 13, 12, 11).time())
True
До Python 3.5 объекты datetime.time() считались ложными, если они представляли полночь по UTC. Это могло приводить к трудноуловимым ошибкам. В следующих примерах if not может выполниться не потому, что created_time равен None, а потому, что время — полночь.
def create(created_time=None) -> None:
if not created_time:
created_time = datetime.now().time()
Можно исправить это, явно проверяя на None:
def create(created_time=None) -> None:
if created_time is None:
created_time = datetime.now().time()
👉@BookPython
int('୧৬𝟙༣')
Out:
1613
Цифры 0 1 2 3 4 5 6 7 8 9 — это не единственные символы, которые считаются цифрами. Python следует правилам Unicode и считает «цифрами» сотни различных символов. Вот полный список таких символов.
Это влияет на такие функции, как int, unicode.isdecimal и даже re.match:
# Пример 1
int('෯')
# Вывод:
9
# Пример 2
'٢'.isdecimal()
# Вывод:
True
# Пример 3
import re
bool(re.match(r'\d', '౫'))
# Вывод:
True
👉@BookPythonexcept перехваченное исключение автоматически сохраняется в атрибуте __context__ создаваемого исключения. В результате при выводе будут показаны оба исключения:
try:
1 / 0
except ZeroDivisionError:
raise ValueError('Zero!')
(most recent call last):
File "test.py", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 4, in <module>
raise ValueError('Zero!')
ValueError: Zero!
Кроме того, вы можете явно указать причинное исключение, использовав конструкцию raise … from. Тогда в атрибут __cause__ нового исключения будет помещено исходное:
division_error = None
try:
1 / 0
except ZeroDivisionError as e:
division_error = e
raise ValueError('Zero!') from division_error
(most recent call last):
File "test.py", line 4, in <module>
1 / 0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "test.py", line 8, in <module>
raise ValueError('Zero!') from division_error
ValueError: Zero!
👉@BookPythongc.get_objects():
In [1]: class A:
...: def __init__(self, x):
...: self._x = x
...:
...: def __repr__(self):
...: class_name = type(self).__name__
...: x = self._x
...: return f'{class_name}({x!r})'
...:
In [2]: A(1)
Out[2]: A(1)
In [3]: A(2)
Out[3]: A(2)
In [4]: A(3)
Out[4]: A(3)
In [5]: [x for x in gc.get_objects() if isinstance(x, A)]
Out[5]: [A(1), A(2), A(3)]
👉@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
Если же число менеджеров контекста заранее неизвестно, лучше подойдёт более продвинутый инструмент. contextlib.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
]
👉@BookPythonelse может располагаться не только после if, но и после for и while. Код внутри else выполняется, если цикл не был прерван оператором break.
Обычный способ использования этого — найти что-то в цикле и выйти из него через break, когда нужный элемент найден:
>>> first_odd = None
>>> for x in [2, 3, 4, 5]:
... if x % 2 == 1:
... first_odd = x
... break
... else:
... raise ValueError('В списке нет нечетных элементов')
...
>>> first_odd
3
>>> for x in [2, 4, 6]:
... if x % 2 == 1:
... first_odd = x
... break
... else:
... raise ValueError('В списке нет нечетных элементов')
...
...
ValueError: В списке нет нечетных элементов
👉@BookPython
Available now! Telegram Research 2025 — the year's key insights 
