Библиотека Python разработчика | Книги по питону
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍 По всем вопросам @evgenycarter РКН clck.ru/3Ko7Hq
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام Библиотека Python разработчика | Книги по питону
تُعد قناة Библиотека Python разработчика | Книги по питону (@bookpython) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 18 326 مشتركاً، محتلاً المرتبة 7 317 في فئة التكنولوجيات والتطبيقات والمرتبة 36 872 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 18 326 مشتركاً.
بحسب آخر البيانات بتاريخ 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”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 06 يونيو, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
except Exception, а не голый except:
try:
foreign()
except Exception:
logging.warn('fail', exc_info=True)
Голый except эквивалентен except BaseException. А разница между BaseException и Exception в том, что BaseException включает исключения, которые, как правило, ловить не следует, например, KeyboardInterrupt.
👉@BookPython[] можно переопределить, реализовав магический метод __getitem__. Это позволяет, например, создать объект, который виртуально содержит бесконечное количество повторяющихся элементов:
class Cycle:
def __init__(self, lst):
self._lst = lst
def __getitem__(self, index):
return self._lst[index % len(self._lst)]
print(Cycle(['a', 'b', 'c'])[100]) # 'b'
Необычность оператора [] в Python в том, что он поддерживает особый синтаксис. Его можно использовать не только так: [2], но и так: [2:10], [2:10:2], [2::2] или даже [:]. Смысл такой записи — [start:stop:step], но в ваших собственных объектах вы можете использовать этот синтаксис как угодно.
Что же передаётся в __getitem__ в таких случаях? Объекты slice созданы специально для этого.
Пример:
class Inspector:
def __getitem__(self, index):
print(index)
Inspector()[1]
# 1
Inspector()[1:2]
# slice(1, 2, None)
Inspector()[1:2:3]
# slice(1, 2, 3)
Inspector()[:]
# slice(None, None, None)
Inspector()[:, 0, :]
# (slice(None, None, None), 0, slice(None, None, None))
Объект slice сам по себе ничего не делает — он просто хранит атрибуты start, stop и step:
s = slice(1, 2, 3)
print(s.start) # 1
print(s.stop) # 2
print(s.step) # 3
👉@BookPythonoverride), в других — это необязательно (в Java можно, но не обязательно использовать аннотацию @Override). В Python нет ни обязательного, ни стандартного способа обозначать такие методы (некоторые программисты применяют пользовательский декоратор @override, который ничего не делает, а служит только для читаемости кода).
Перегрузка, напротив, — это наличие нескольких функций с одним и тем же именем, но разными сигнатурами. Это поддерживается в таких языках, как Java и C++, и часто используется как способ предоставления значений по умолчанию:
class Foo {
public static void main(String[] args) {
System.out.println(Hello());
}
public static String Hello() {
return Hello("world");
}
public static String Hello(String name) {
return "Hello, " + name;
}
}
Python не поддерживает поиск функций по сигнатурам, только по именам. Вы можете написать код, который явно анализирует типы и количество аргументов, но это обычно выглядит громоздко и не очень красиво:
def quadrilateral_area(*args):
if len(args) == 4:
quadrilateral = Quadrilateral(*args)
elif len(args) == 1:
quadrilateral = args[0]
else:
raise TypeError()
return quadrilateral.area()
Если вам нужны подсказки типов для такой реализации, модуль typing предоставляет декоратор @overload, который можно использовать следующим образом:
from typing import overload
@overload
def quadrilateral_area(
q: Quadrilateral
) -> float: ...
@overload
def quadrilateral_area(
p1: Point, p2: Point,
p3: Point, p4: Point
) -> float: ...
👉@BookPython__file__ возвращает относительный путь к нему:
$ cat test/foo.py
print(__file__)
$ python test/foo.py
test/foo.py
Типичное применение этого — определить путь, где находится сам скрипт. Это может быть полезно, например, для поиска других файлов: конфигураций, ресурсов и т.д.
Чтобы получить абсолютный путь из относительного, можно использовать os.path.abspath. Поэтому распространённый приём для получения пути к директории скрипта выглядит так:
import os
dir_path = os.path.dirname(
os.path.abspath(__file__)
)
👉@BookPythonprint(), либо подключают logging, но каждый раз пишут кучу однотипного кода. Я так тоже делал. Но потом вывел себе простую универсальную схему, которую теперь кидаю в каждый новый проект:
import logging
def setup_logger(name: str) -> logging.Logger:
logger = logging.getLogger(name)
if not logger.hasHandlers():
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(name)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
logger = setup_logger(__name__)
logger.info("Скрипт стартовал")
Что мы получаем:
* Удобный формат времени и уровня лога
* Защиту от дублирования логов (если модуль импортируется несколько раз)
* Готовность к масштабированию (можно легко добавить файл-логгер)
Если вы устали от print(), просто сохраните себе этот сниппет — он сэкономит вам время и нервы.
Пользуетесь ли вы встроенным logging, или предпочитаете что-то вроде loguru?
👉@BookPythonlogging — вызывать функции напрямую, без создания объекта логгера:
import logging
logging.error('xxx')
Этот глобальный логгер можно настроить с помощью вызова logging.basicConfig():
import logging
logging.basicConfig(format='-- %(message)s --')
logging.error('xxx') # -- xxx --
Однако у basicConfig есть свои ограничения. Во-первых, срабатывает только первый вызов — все последующие игнорируются. Во-вторых, любая функция, записывающая лог, может вызвать basicConfig, поэтому конфигурацию нужно задавать до любых сообщений:
import logging
logging.error('xxx') # ERROR:root:xxx
logging.basicConfig(format='-- %(message)s --')
logging.error('xxx') # ERROR:root:xxx
👉@BookPythonfunctools.partial
Как упростить код и избежать дублирования с помощью functools.partial.
Допустим, у нас есть функция send_email(to, subject, body, is_html=False), и мы часто вызываем её с одним и тем же параметром is_html=True.
Вместо того чтобы каждый раз писать это явно, можно создать частичную функцию:
from functools import partial
send_html_email = partial(send_email, is_html=True)
# Теперь можно вызывать проще:
send_html_email("user@example.com", "Привет", "<b>Как дела?</b>")
Это удобно, если вы хотите предварительно зафиксировать часть аргументов, например:
* логгеры с предустановленным уровнем
* коннекторы с общими параметрами
* команды CLI с типовыми флагами
Таким образом, вы уменьшаете дублирование и делаете код читаемее. А ещё это красивый способ внедрить DI без фреймворков — просто передайте partial.
👉@BookPythonfloat в Python используют оборудование вашего компьютера напрямую, поэтому любое значение представляется внутренне в виде двоичной дроби.
Это означает, что вы обычно работаете с приближениями, а не с точными значениями:
>>> format(0.1, '.17f')
'0.10000000000000001'
Модуль decimal позволяет использовать десятичную арифметику с произвольной точностью:
>>> from decimal import Decimal
>>> Decimal(1) / Decimal(3)
Decimal('0.3333333333333333333333333333')
Но и этого может быть недостаточно:
>>> Decimal(1) / Decimal(3) * Decimal(3) == Decimal(1)
False
Для абсолютно точных вычислений можно использовать модуль fractions, который хранит любое число как рациональное:
>>> from fractions import Fraction
>>> Fraction(1) / Fraction(3) * Fraction(3) == Fraction(1)
True
Очевидное ограничение — всё равно приходится использовать приближения для иррациональных чисел, таких как π.
👉@BookPython__new__, который создаёт и возвращает новый объект. Затем вызывается метод __init__ для инициализации состояния этого объекта.
Однако, если __new__ возвращает объект, который не является экземпляром исходного класса, метод __init__ не будет вызван. Это связано с тем, что возвращаемый объект, вероятно, уже создан другим классом, и его __init__ уже был выполнен:
class Foo:
def __new__(cls, x):
return dict(x=x)
def __init__(self, x):
print(x) # Никогда не вызывается
print(Foo(0))
Важно: не следует создавать экземпляры того же класса в __new__ с использованием обычного конструктора (Foo(...)). Это может привести к двойному вызову __init__ или даже к бесконечной рекурсии.
Пример бесконечной рекурсии:
class Foo:
def __new__(cls, x):
return Foo(-x) # Рекурсия
Пример двойного вызова __init__:
class Foo:
def __new__(cls, x):
if x < 0:
return Foo(-x)
return super().__new__(cls)
def __init__(self, x):
print(x)
self._x = x
Правильный способ:
class Foo:
def __new__(cls, x):
if x < 0:
return cls.__new__(cls, -x)
return super().__new__(cls)
def __init__(self, x):
print(x)
self._x = x
👉@BookPythontyper
Раньше для CLI-приложений на Python я использовал argparse, потом был click, но недавно полностью перешёл на typer. Это библиотека от автора FastAPI, и она реально 🔥
Вот простой пример:
import typer
app = typer.Typer()
@app.command()
def hello(name: str, age: int = 18):
print(f"Привет, {name}! Тебе {age} лет.")
if __name__ == "__main__":
app()
Теперь можно запускать в терминале:
$ python main.py hello Alice --age 30
Привет, Alice! Тебе 30 лет.
Что круто:
- Автоматически генерируется --help
- Пишется почти как обычная функция
- Есть автокомплит в оболочках (bash/zsh)
- Поддержка аннотаций типов и валидации "из коробки"
Если ты всё ещё страдаешь с argparse, рекомендую попробовать typer. Особенно если ты уже кайфуешь от FastAPI — синтаксис и подход очень похожи.
👉@BookPythoncollections.defaultdict позволяет создать словарь, который возвращает значение по умолчанию, если запрашиваемого ключа нет (вместо того чтобы выбрасывать KeyError). Для создания defaultdict нужно передать не само значение по умолчанию, а фабрику для его создания.
Это позволяет создавать словари с потенциально бесконечным уровнем вложенности, благодаря чему можно делать что-то вроде d[a][b][c]...[z].
>>> def infinite_dict():
... return defaultdict(infinite_dict)
...
>>> d = infinite_dict()
>>> d[1][2][3][4] = 10
>>> dict(d[1][2][3][5])
{}
Такое поведение называется "автовивификацией" (autovivification) — термин пришёл из языка Perl.
👉@BookPythonNotImplementedError:
def human_name(self):
raise NotImplementedError
Хотя этот подход довольно распространён и даже поддерживается IDE (например, PyCharm считает такие методы абстрактными), у него есть недостаток: ошибка возникает только при вызове метода, а не при создании экземпляра класса.
Чтобы избежать этой проблемы, используйте модуль abc:
from abc import ABCMeta, abstractmethod
class Service(metaclass=ABCMeta):
@abstractmethod
def human_name(self):
pass
Также важно помнить, что NotImplemented — это не то же самое, что NotImplementedError. NotImplemented — это специальное значение (как True и False), а не исключение. Оно используется, например, в специальных методах (__eq__(), __add__() и др.), чтобы сообщить Python, что операция не реализована для данного типа, и попытаться вызвать альтернативный метод (например, если a.__add__(b) возвращает NotImplemented, Python попробует вызвать b.__radd__(a)).
👉@BookPython
متاح الآن! بحث تيليغرام 2025 — أهم رؤى العام 
