#python #variadic-functions #dry #type-hinting #python-typing
Вопрос:
Я искал вокруг и, похоже, не могу найти ничего, что действительно отвечало бы на этот тип проблемы или давало бы полезные рекомендации по ней.
У меня есть несколько функций, которые принимают один и тот же набор параметров, и я пытаюсь уменьшить количество параметров, которые должны быть определены вручную в каждой функции, чтобы я мог сосредоточиться на определении и обработке параметров, уникальных для данной функции. Все это при сохранении набора текста и другой полезной информации для абонентов. Я понимаю, что мне просто нужно смириться с этим и написать кучу параметров для каждого из них, но это кажется грязным и похоже, что должен быть лучший способ решения этой проблемы.
В качестве «практического» примера у меня есть что-то вроде следующего:
from typing import Any, Optional
def get_a_objects(name: str, limit: int, ... other common params to all objects ..., a_specific_param1: Any, ... params specific to A objects ..., limit: int, offset:int, create_ts: datetime, ... other common params to all list/get endpoints ...):
pass
def get_a_object(id: int):
pass
def set_a_objects(id: int, name: Optional[str] = None, ... other common params to all objects ..., a_specific_param1: Any, ... params specific to A objects ...):
pass
def get_b_objects(name: str, limit: int, ... other common params to all objects ..., a_specific_param1: Any, ... params specific to B objects ..., limit: int, offset:int, create_ts: datetime, ... other common params to all list/get endpoints ...):
pass
def get_b_object(id: int):
pass
def set_b_objects(name: str, limit: int, ... other common params to all objects ..., b_specific_param1: Any, ... params specific to B objects ...):
pass
...
Где число общих параметров велико, и число параметров, специфичных для объекта, велико, и число общих параметров get/list также велико. То, о чем я думал, это нечто похожее на
def a_get_params(f):
def wrapped(*args, ... params specific to A objects ..., **kwargs):
return f(*args, **{**dict(params specific to A objects), **kwargs})
return wrapped
Где я бы затем украсил все конкретные функции «А», например, этим декоратором, и мог бы сделать то же самое для конкретных функций «Б» или для конкретных функций «списка» и просто складывал декораторы по мере необходимости.
Хотя это тоже кажется излишне сложным. Плюс вызов help(get_a_objects)
, как только он будет оформлен, я не верю, что на самом деле будут отображаться какие-либо параметры A или их типы, что в любом случае разрушает смысл ввода информации?
Кто-нибудь сталкивался с способом преодолеть это, просто не вводя 30 параметров для каждого отдельного определения/вызова функции, особенно когда большинство из них являются необязательными? Плюс потом я получаю линтеры, кричащие на меня за то, что у меня есть функции со слишком большим количеством параметров… иногда это нормально игнорировать, но когда речь идет обо всех функциях, это определенно заставляет меня чувствовать, что я делаю что-то не так, и должен быть лучший способ.
Заранее спасибо!
Комментарии:
1. Есть ли какая-либо причина, по которой вы не можете собрать общие параметры в один объект, такой как
dict
,namedtuple
,UserDict
, класс данных и т. Д.?2. @Брайан, может быть? Я не уверен, не могли бы вы привести такой пример? Как бы то ни было, если бы я создал кучу классов/объектов и передал их другим, мне все равно пришлось бы разложить/сериализовать их в JSON, поскольку это часть клиента HTTP API на основе JSON. Используя словари для их передачи, я думаю, что потерял бы информацию о вводе, и мне было бы сложнее кэшировать любые запросы с помощью функций. например, lru_cache.