Создавать объекты внутри или снаружи функций в Python?

Я работаю над веб-API Python, используя FastAPI.

В настоящее время это очень маленькое приложение, но я ожидаю, что в ближайшие несколько месяцев в нем будет несколько сотен routes и services.

Это пример route у меня есть:

my_service_1 = MyService1()
my_service_2 = MyService2()

@router.get("/route-1")
def route_1():
    # Do something with the services

@router.get("/route-2")
def route_2():
    # Do something with the services

@router.get("/route-3")
def route_3():
    # Do something with the services

Я оставил объявление сервисов вверху файла для удобства, чтобы все маршруты в файле могли легко их использовать.

Мой вопрос заключается в том, что с сотнями таких файлов, как только приложение запустится, все маршруты будут зарегистрированы, поэтому будут созданы экземпляры всех служб. Это плохая идея? Не приведет ли это к слишком большому использованию памяти, учитывая, что все службы теперь загружены в память?

Будет ли что-то подобное лучше с точки зрения производительности/использования памяти?

@router.get("/route-1")
def route_1():
    my_service_1 = MyService1()
    my_service_2 = MyService2()
    # Do something with the services

@router.get("/route-2")
def route_2():
    my_service_1 = MyService1()
    my_service_2 = MyService2()
    # Do something with the services

@router.get("/route-3")
def route_3():
    my_service_1 = MyService1()
    my_service_2 = MyService2()
    # Do something with the services

Пожалуйста, простите меня, если это не pythonic способ сделать что-то, я пришел из C#.


person AndreFeijo    schedule 19.06.2020    source источник


Ответы (1)


TL;DR

Создание новой службы при каждом запросе может быть дорогостоящим, и я советую, если вы можете, создавать их все в начале и держать их готовыми к будущим запросам. Вы ответите быстрее (это зависит от сервиса) и заранее будете знать, какие ресурсы нужны приложению.

Ответ прост: ответа нет.

Помимо шуток, все зависит от варианта использования. Если у вас есть целый сервер, выделенный для вашего приложения, и никакое другое приложение не запущено, вы можете использовать все доступные ресурсы (но не обязательно), и, таким образом, вы не связаны жесткими ограничениями. С другой стороны, вы можете работать на ограниченных ресурсах, таких как общий сервер (например, облачный сервер), где могут работать другие службы, и переключение с одного сервера на другой может привести к потере информации.

Я не уверен, что вы имеете в виду под «сервисом», но если это просто класс, который можно использовать для нескольких запросов, то мой совет — создать их экземпляры в модуле (или пакете) и повторно использовать их в запросах.

Конечно, если они требуют много ресурсов, скажем, 0,5 ГБ ОЗУ, а у вашего сервера всего 1 ГБ ОЗУ, а пользователи запрашивают разные службы, как только вы создадите вторую службу, система рухнет.

По моему опыту, Python (и особенно последние версии) достаточно эффективен практически для всех случаев использования. Прелесть в том, что вы можете масштабировать его, но опять же, все зависит от ожидаемого использования, контекста (какие сервисы) и ограничений.

Пример

Недавно я использовал библиотеку https://www.python-httpx.org/ для связи с другим сервисом в своем веб-приложении. Я создавал экземпляр клиента (или сеанс для тех, кто пришел из requests) для каждого запроса. В какой-то момент я начал получать некоторые ошибки из-за увеличения трафика.

Проблема заключалась в создании экземпляров при каждом отдельном запросе и наличии тысяч таких запросов, что означало постоянное соединение со службой. Итак, я создал экземпляр клиента, который подключался один раз при запуске сервера и был разделен между различными функциями/маршрутами. Это было даже быстрее, потому что мне не нужно было подключаться при каждом запросе, а только один раз.

person lsabi    schedule 19.06.2020
comment
создавайте их экземпляры в модуле (или пакете) и повторно используйте их в запросах спасибо за предложение! - person AndreFeijo; 20.06.2020
comment
Пожалуйста. Убедитесь, что все ваши службы запущены. См. fastapi.tiangolo.com/advanced/events для получения дополнительной информации. - person lsabi; 20.06.2020