Библиотека Python разработчика | Книги по питону
18.6K subscribers
1.06K photos
403 videos
82 files
1.1K links
Погружение в CPython и архитектуру. Разбираем неочевидное поведение (GIL, Memory), Best Practices (SOLID, DDD) и тонкости Django/FastAPI. Решаем задачи с подвохом и оптимизируем алгоритмы. 🐍

По всем вопросам @evgenycarter

РКН clck.ru/3Ko7Hq
Download Telegram
Популярный способ объявить абстрактный метод в Python — это выбросить исключение NotImplementedError:


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)).

📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Как упростить работу с аргументами в командной строке с помощью typer

Раньше для 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 — синтаксис и подход очень похожи.

📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🚀 Подборка полезных IT каналов в Max


Системное администрирование, DevOps 📌

https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.

1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌

https://max.ru/cpp_lib Библиотека C/C++ разработчика

Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика

Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика

GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных

Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков

Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов

Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻

Шутки программистов 📌
https://max.ru/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free

Книги, статьи для дизайнеров 📌

https://max.ru/odesigners Статьи, книги для дизайнеров

Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике

Вакансии 📌
https://max.ru/progjob Вакансии в IT

Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных


Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
2👎1
Создание объекта в Python включает два ключевых этапа. Сначала вызывается метод __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


📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Встроенные значения float в 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


Очевидное ограничение — всё равно приходится использовать приближения для иррациональных чисел, таких как π.

📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍1
💡 Как избежать повторения кода с помощью functools.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.

📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
🚀 Как логировать без боли в Python

Как настроить логирование в Python один раз — и больше к этому не возвращаться.

Обычно начинающие разработчики либо используют print(), либо подключают 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?

📲 Мы в MAX

👉@BookPython
Please open Telegram to view this post
VIEW IN TELEGRAM
👍52