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

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

Ir al canal en Telegram

Погружение в 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 299 en la categoría Tecnologías y Aplicaciones y el puesto 36 904 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 03 junio, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de -85, y en las últimas 24 horas de -8, 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.04%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 2.53% de reacciones respecto al total de suscriptores.
  • Alcance de las publicaciones: Cada publicación recibe en promedio 1 107 visualizaciones. En el primer día suele acumular 463 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 04 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.

18 328
Suscriptores
-824 horas
-357 días
-8530 días
Archivo de publicaciones
Функция round округляет число до заданной точности в десятичных знаках.

>>> round(1.2)
1
>>> round(1.8)
2
>>> round(1.228, 1)
1.2
Также можно задать отрицательную точность:

>>> round(413.77, -1)
410.0
>>> round(413.77, -2)
400.0
round возвращает значение того же типа, что и входное число:

>>> type(round(2, 1))
<class 'int'>

>>> type(round(2.0, 1))
<class 'float'>

>>> type(round(Decimal(2), 1))
<class 'decimal.Decimal'>

>>> type(round(Fraction(2), 1))
<class 'fractions.Fraction'>
Для собственных классов можно определить поведение округления с помощью метода __round__:

>>> class Number(int):
...   def __round__(self, p=-1000):
...     return p
...
>>> round(Number(2))
-1000
>>> round(Number(2), -2)
-2
Значения округляются до ближайшего кратного 10 ** (-precision). Например, при precision=1, значение округляется до кратного 0.1: round(0.63, 1) возвращает 0.6. Если два значения одинаково близки, округление происходит в сторону чётного числа:

>>> round(0.5)
0
>>> round(1.5)
2
Иногда округление чисел с плавающей точкой может казаться неожиданным:

>>> round(2.85, 1)
2.9
Это связано с тем, что большинство десятичных дробей не могут быть точно представлены в формате float:

>>> format(2.85, '.64f')
'2.8500000000000000888178419700125232338905334472656250000000000000'
Если нужно округление "в большую сторону при 0.5" (round half up), можно использовать decimal.Decimal:

>>> from decimal import Decimal, ROUND_HALF_UP
>>> Decimal(1.5).quantize(0, ROUND_HALF_UP)
Decimal('2')
>>> Decimal(2.85).quantize(Decimal('1.0'), ROUND_HALF_UP)
Decimal('2.9')
>>> Decimal(2.84).quantize(Decimal('1.0'), ROUND_HALF_UP)
Decimal('2.8')
📲 Мы в MAX 👉@BookPython

Стандартный модуль json имеет интерфейс командной строки, который может быть полезен для форматирования JSON только с помощью Python. Модуль для этого называется json.tool и предназначен для вызова следующим образом:

$ echo '{"a": [], "b": "c"}' | python -m json.tool
{
    "a": [],
    "b": "c"
}
📲 Мы в MAX 👉@BookPython

Чтобы немедленно остановить выполнение программы на Python, следует использовать sys.exit(). Альтернативой является функция exit(), однако она предназначена для использования в интерактивном режиме. Благодаря строковому представлению, она может помочь пользователям, которые пытаются завершить сессию, используя exit (что поддерживается многими оболочками):

>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>> str(exit)
'Use exit() or Ctrl-D (i.e. EOF) to exit'
И exit(), и sys.exit() на самом деле не завершают программу, а просто выбрасывают исключение SystemExit. SystemExit — это прямой подкласс BaseException, а значит, он не может быть перехвачен через except Exception, но может быть перехвачен через except BaseException или через голый except:.

>>> try:
...     exit()
... except:
...     'Nothing'
...
'Nothing'
Поскольку это может быть проблемой, можно использовать функцию os._exit. Она не выбрасывает никаких исключений — просто завершает текущий процесс. Однако это означает, что блоки finally, а также завершающие действия менеджеров контекста не будут выполнены.

$ python3
Python 3.4.3 (default, Apr 28 2015, 13:37:07)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     os._exit(42)
... finally:
...     print('Bye!')
...
$ ...
📲 Мы в MAX 👉@BookPython

Иногда программное обеспечение начинает вести себя странно в продакшене. Вместо того чтобы просто перезапустить его, вы, вероятно, захотите понять, что именно происходит, чтобы позже это исправить. Очевидный способ сделать это — проанализировать, что делает программа, и попытаться угадать, какой участок кода выполняется. Безусловно, корректная система логирования облегчает эту задачу, но логи приложения могут быть недостаточно подробными — либо по замыслу, либо из-за настроек, ограничивающих уровень логирования. В таком случае может пригодиться strace. Это утилита Unix, которая отслеживает системные вызовы. Вы можете запустить её заранее — strace python script.py — но чаще бывает удобнее подключиться к уже работающему процессу: strace -p PID.
$ cat test.py
with open('/tmp/test', 'w') as f:
    f.write('test')
$ strace python test.py 2>&1 | grep open | tail -n 1
open("/tmp/test", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3
Каждая строка в выводе strace содержит имя системного вызова, его аргументы в скобках и возвращаемое значение. Поскольку некоторые аргументы являются выходными параметрами (используются для возврата результата, а не для передачи данных), вывод строки может быть прерван до завершения системного вызова. В следующем примере вывод приостанавливается до тех пор, пока кто-то не введёт данные в STDIN:

$ strace python -c 'input()'
...
read(0,
📲 Мы в MAX 👉@BookPython

🚀 Подборка полезных 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 и др. https://max.ru/tipsysdmin Типичный Сисадмин 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование 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 Свежие новости Москвы

У Python очень короткий список встроенных констант. Одна из них — Ellipsis, которую также можно записать как .... Эта константа не имеет особого значения для интерпретатора, но используется в ситуациях, где такой синтаксис уместен. В библиотеке NumPy Ellipsis поддерживается в качестве аргумента для __getitem__, например, x[...] возвращает все элементы массива x. PEP 484 придаёт Ellipsis дополнительный смысл: Callable[..., type] используется для обозначения типа вызываемых объектов без указания типов аргументов. Наконец, ... можно использовать, чтобы показать, что функция ещё не реализована. Это полностью допустимый Python-код:

def x():
    ...
📲 Мы в MAX 👉@BookPython

💡10 функций, для продвинутых Python-разработчиков 1. Разворачиваем вложенных списков любой глубины

flatten = lambda lst: [x for sub in lst for x in (flatten(sub) if isinstance(sub, list) else [sub])]
2. Декоратор для мемоизации результатов функции

memoize = lambda f: (lambda *args, _cache={}, **kwargs: _cache.setdefault((args, tuple(kwargs.items())), f(*args, **kwargs)))
3. Разбиение списка на куски длины n

chunked = lambda lst, n: [lst[i:i+n] for i in range(0, len(lst), n)]
4. Уникализация последовательности с сохранением порядка

uniq = lambda seq: list(dict.fromkeys(seq))
5. Глубокий доступ к вложенным ключам словаря

deep_get = lambda d, *keys: __import__('functools').reduce(lambda a, k: a.get(k) if isinstance(a, dict) else None, keys, d)
6. Преобразование Python-объекта в читаемый JSON

pretty_json = lambda obj: __import__('json').dumps(obj, ensure_ascii=False, indent=2)
7. Чтение последних n строк файла (аналог tail)

tail = lambda f, n=10: list(__import__('collections').deque(open(f), maxlen=n))
8. Выполнение shell-команды и возврат вывода

sh = lambda cmd: __import__('subprocess').run(cmd, shell=True, check=True, capture_output=True).stdout.decode().strip()
9. Быстрое объединение путей

path_join = lambda *p: __import__('os').path.join(*p)
10. Группировка списка словарей по значению ключа

group_by = lambda seq, key: {k: [d for d in seq if d.get(key) == k] for k in set(d.get(key) for d in seq)}
📲 Мы в MAX 👉@BookPython

Если вы хотите итерироваться одновременно по нескольким итерируемым объектам, функция zip может быть хорошим выбором. Она возвращает генератор, который выдаёт кортежи, содержащие по одному элементу из каждого исходного итерируемого объекта:

In : eng = ['one', 'two', 'three']
In : ger = ['eins', 'zwei', 'drei']
In : for e, g in zip(eng, ger):
    ...:     print('{e} = {g}'.format(e=e, g=g))
    ...:
Вывод:
one = eins  
two = zwei  
three = drei
Обратите внимание, что zip принимает итерируемые объекты как отдельные аргументы, а не в виде списка аргументов. Чтобы «развернуть» значения (unzip), можно использовать оператор *:

In : list(zip(*zip(eng, ger)))
Out: [('one', 'two', 'three'), ('eins', 'zwei', 'drei')]
📲 Мы в MAX 👉@BookPython

Иногда в тестах нужно сравнивать сложные структуры, игнорируя некоторые значения. Обычно это делается путем сравнения отдельных значений внутри структуры:

>>> d = dict(a=1, b=2, c=3)
>>> assert d['a'] == 1
>>> assert d['c'] == 3
Однако можно создать специальное значение, которое будет считаться равным любому другому значению:

>>> assert d == dict(a=1, b=ANY, c=3)
Это легко реализовать, определив метод __eq__:

>>> class AnyClass:
...     def __eq__(self, another):
...         return True
... 
>>> ANY = AnyClass()
📲 Мы в MAX 👉@BookPython

🚀 Подборка полезных 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 и др. https://max.ru/tipsysdmin Типичный Сисадмин 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование 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 Свежие новости Москвы

Начиная с Python 3.7, модуль contextlib предоставляет декоратор asynccontextmanager, который позволяет определять асинхронные контекстные менеджеры точно так же, как contextmanager:

import asyncio
from contextlib import asynccontextmanager

@asynccontextmanager
async def slow(delay):
    half = delay / 2
    await asyncio.sleep(half)
    yield
    await asyncio.sleep(half)

async def main():
    async with slow(1):
        print('slow')

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Для более старых версий Python можно использовать @asyncio_extras.async_contextmanager. 📲 Мы в MAX 👉@BookPython

Если ты хочешь, чтобы контекстный менеджер при входе или выходе из контекста приостанавливал выполнение корутины, следует использовать асинхронные контекстные менеджеры. Вместо вызова m.__enter__() и m.__exit__() Python в этом случае выполняет await m.__aenter__() и await m.__aexit__() соответственно. Асинхронные контекстные менеджеры нужно использовать с синтаксисом async with:

import asyncio

class Slow:
    def __init__(self, delay):
        self._delay = delay

    async def __aenter__(self):
        await asyncio.sleep(self._delay / 2)

    async def __aexit__(self, *exception):
        await asyncio.sleep(self._delay / 2)

async def main():
    async with Slow(1):
        print('slow')

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
В этом примере класс Slow симулирует задержку при входе и выходе из контекста. 📲 Мы в MAX 👉@BookPython

Начиная с Python 3.5, стало возможно использовать распаковку в литералах словарей и списков. Пример со словарём:

{**{'a': 1}, 'b': 2, **{'c': 3}}
# Результат: {'a': 1, 'b': 2, 'c': 3}
Пример со списком:

[1, 2, *[3, 4]]
# Результат: [1, 2, 3, 4]
Для словарей такая форма даже мощнее, чем функция dict, потому что позволяет переопределять значения:

{**{'a': 1, 'b': 1}, 'a': 2, **{'b': 3}}
# Результат: {'a': 2, 'b': 3}
📲 Мы в MAX 👉@BookPython

Ты можешь создавать словари двумя способами: с помощью литералов или функции dict:

>>> dict(a=1, b=2)
{'a': 1, 'b': 2}
>>> {'a': 1, 'b': 2}
{'a': 1, 'b': 2}
Литералы работают быстрее, чем dict, но у функции есть свои преимущества. Во-первых, не нужно ставить дополнительные кавычки. Однако это работает только в том случае, если все ключи — допустимые идентификаторы Python:

>>> dict(a=1)
{'a': 1}
>>> dict(1='a')
  File "<stdin>", line 1
SyntaxError: keyword can't be an expression
Во-вторых, ты не сможешь случайно указать один и тот же ключ дважды:

>>> {'a': 1, 'a': 1}
{'a': 1}
>>> dict(a=1, a=1)
  File "<stdin>", line 1
SyntaxError: keyword argument repeated
В-третьих, легко создать новый словарь на основе уже существующего:

>>> d = dict(b=2)
>>> dict(a=1, **d)
{'a': 1, 'b': 2}
Но учти, что ключи нельзя переопределять при таком способе:

>>> dict(b=3, **d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type object got multiple values for keyword argument
📲 Мы в MAX 👉@BookPython

Если ты хочешь запустить код с изменённой глобальной переменной, лучше использовать контекстный менеджер, а не менять её напрямую:

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()
📲 Мы в MAX 👉@BookPython

🚀 Подборка полезных 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++ разработчика Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование 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 Свежие новости Москвы

Существует две встроенные функции, которые позволяют анализировать итерируемые объекты без необходимости писать тривиальные и избыточные циклы for. Это all и any. any возвращает True, если хотя бы одно значение истинно; all возвращает True, только если все значения истинны. Для пустого итерируемого объекта all возвращает True, а anyFalse. Обе функции особенно полезны в сочетании со списковыми включениями (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 зачастую взаимозаменяемы благодаря законам де Моргана. Используй ту, с которой код будет понятнее. 📲 Мы в MAX 👉@BookPython

Иногда нужно создать функцию на основе более универсальной. Например, у функции int() есть параметр 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]
📲 Мы в MAX 👉@BookPython

В Python нет поддержки асинхронных операций с файлами. Чтобы сделать их неблокирующими, нужно использовать отдельные потоки. Для асинхронного выполнения кода в потоке следует использовать метод loop.run_in_executor. Сторонний модуль aiofiles делает всё это за тебя, предоставляя простой и удобный интерфейс:

async with aiofiles.open('filename', mode='r') as f:
    contents = await f.read()
📲 Мы в MAX 👉@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()
📲 Мы в MAX 👉@BookPython