Библиотека Python разработчика | Книги по питону
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq
Mostrar más📈 Análisis del canal de Telegram Библиотека Python разработчика | Книги по питону
El canal Библиотека Python разработчика | Книги по питону (@bookpython) en el segmento lingüístico de Ruso es un actor destacado. Actualmente la comunidad reúne a 18 328 suscriptores, ocupando la posición 7 307 en la categoría Tecnologías y Aplicaciones y el puesto 36 869 en la región Rusia.
📊 Métricas de audiencia y dinámica
Desde su creación el невідомо, el proyecto ha mostrado un crecimiento acelerado, reuniendo a 18 328 suscriptores.
Según los últimos datos del 04 junio, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de -86, y en las últimas 24 horas de -1, conservando un alto alcance.
- Estado de verificación: No verificado
- Tasa de interacción (ER): El promedio de interacción de la audiencia es 6.07%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 2.61% de reacciones respecto al total de suscriptores.
- Alcance de las publicaciones: Cada publicación recibe en promedio 1 112 visualizaciones. En el primer día suele acumular 479 visualizaciones.
- Reacciones e interacción: La audiencia responde de forma activa: el promedio de reacciones por publicación es 2.
- Intereses temáticos: El contenido se centra en temas clave como numbers, yield, модуль, none, декоратор.
📝 Descripción y política de contenido
El autor describe el recurso como un espacio para expresar opiniones subjetivas:
“Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍
По всем вопросам @evgenycarter
РКН clck.ru/3Ko7Hq”
Gracias a la alta frecuencia de actualizaciones (últimos datos recibidos el 05 junio, 2026), el canal mantiene la vigencia y un amplio alcance. La analítica demuestra que la audiencia interactúa activamente con el contenido, lo que lo convierte en un punto de referencia dentro de la categoría Tecnologías y Aplicaciones.
__lt__ для <
‣ __gt__ для >
‣ __le__ для <=
‣ __ge__ для >=
‣ __eq__ для ==
‣ __ne__ для !=
Если некоторые из этих методов не определены или возвращают NotImplemented, применяются следующие правила:
‣ a.__lt__(b) эквивалентно b.__gt__(a)
‣ a.__le__(b) эквивалентно b.__ge__(a)
‣ a.__eq__(b) эквивалентно not a.__ne__(b) (обратите внимание, что в этом случае a и b не меняются местами)
Однако, из a >= b и a != b не следует автоматически, что a > b.
Декоратор functools.total_ordering создает все шесть методов на основе __eq__ и одного из следующих: __lt__, __gt__, __le__ или __ge__.
from functools import total_ordering
@total_ordering
class User:
def __init__(self, pk, name):
self.pk = pk
self.name = name
def __le__(self, other):
return self.pk <= other.pk
def __eq__(self, other):
return self.pk == other.pk
assert User(2, 'Vadim') < User(13, 'Catherine')
👉@BookPythondatetime имеют специальный интерфейс для поддержки часовых поясов (а именно атрибут tzinfo), но сам модуль реализует этот интерфейс лишь частично, оставляя остальную работу другим модулям.
Наиболее популярный модуль для этой задачи — pytz.
Хитрость в том, что pytz не полностью соответствует интерфейсу tzinfo. В документации pytz это указано уже в первых строках:
«Эта библиотека отличается от задокументированного Python API для реализаций 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, может напрямую передаваться в атрибут tzinfo, не требует нормализации, хотя работает немного медленнее.
👉@BookPython
>>> '\N{EM DASH}'
'—'
>>> '\u2014'
'—'
Это также совместимо с f-строками:
>>> width = 800
>>> f'Width \N{EM DASH} {width}'
'Width — 800'
👉@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 в экземпляре, а не в классе. Вместо этого стоит использовать фабричный метод, чтобы сделать код красивее:
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.
👉@BookPythonbreak подавляет исключение, если используется в блоке finally, даже когда блок except отсутствует:
for i in range(10):
try:
1 / i
finally:
print('finally')
break
print('after try')
print('after while')
Вывод:
finally after whileТо же самое верно и для
continue, однако его нельзя использовать в блоке finally до версии Python 3.8:
SyntaxError: 'continue' not supported inside 'finally' clause👉@BookPython
await asyncio.sleep(x):
import asyncio
async def do(n=0):
print(n)
await asyncio.sleep(1)
loop.create_task(do(n + 1))
loop.create_task(do(n + 1))
loop = asyncio.get_event_loop()
loop.create_task(do())
loop.run_forever()
Однако создание новой задачи может быть затратным и не требуется, если вы не собираетесь выполнять асинхронные операции (как в функции do из примера).
Другой способ сделать это — использовать функции loop.call_later и loop.call_at, которые планируют вызов асинхронного колбэка:
import asyncio
def do(n=0):
print(n)
loop = asyncio.get_event_loop()
loop.call_later(1, do, n+1)
loop.call_later(1, do, n+1)
loop = asyncio.get_event_loop()
do()
loop.run_forever()
👉@BookPython__call__.
class SavingOrig:
def __init__(self, another_decorator):
self._another = another_decorator
def __call__(self, f):
decorated = self._another(f)
if hasattr(f, 'orig'):
decorated.orig = f.orig
else:
decorated.orig = f
return decorated
saving_orig = SavingOrig
Последняя строка позволяет одновременно дать классу имя в стиле CamelCase и сохранить имя декоратора в стиле snake_case.
👉@BookPython__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 зарезервировано для внутренних состояний ошибок, поэтому оно автоматически преобразуется в -2.
👉@BookPython
keys = ['a', 'b', 'c']
{k: True for k in keys}
Результат:
{'a': True, 'b': True, 'c': True}
Однако у класса dict есть специальный метод класса fromkeys, предназначенный именно для этого случая:
dict.fromkeys(keys, True)
Результат:
{'a': True, 'b': True, 'c': True}
👉@BookPythonexcept переменные, в которых хранятся перехваченные исключения, удаляются из locals(), даже если они существовали раньше:
>>> e = 2
>>> try:
... 1/0
... except Exception as e:
... pass
...
>>> e
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined
Если нужно сохранить ссылку на исключение, используйте другую переменную:
>>> error = None
>>> try:
... 1/0
... except Exception as e:
... error = e
...
>>> error
ZeroDivisionError('division by zero',)
В Python 2 это правило не действует.
👉@BookPython
¡Ya disponible! Investigación de Telegram 2025 — los principales insights del año 
