Как использовать декоратор для отправки аргументов функции в python
У меня есть набор функций в python, который получает те же 2 параметра + другие параметры.
def myMethodA (param1, param2, specificParm)
do code
def myMethodB (param1, param2, specificParm1 specificParam2)
do code
Я хотел создать декоратор, который заменит необходимость вызова с первыми 2 параметрами, нажав параметры перед вызовом функции:
@withParams()
def myMethodA (specificParam)
do code
Но если я опущу параметры, то декоратор не сможет вызвать его, а если я оставлю их, то вызывающий должен также указать их.
В любом случае, чтобы решить эту проблему? Могу ли я что-то сделать с args* , но все равно назвал параметры для specificParam? Кроме того, как я могу ссылаться на param1 и param2 внутри myMethodA
4 ответа:
Похоже, что вы можете захотеть
functools.partial
. Он возвращает новую функцию с некоторыми уже заданными параметрами:import functools def withParams(func): return functools.partial(func,1,2) @withParams def myMethodA (param1, param2, specificParam): print(param1,param2,specificParam) @withParams def myMethodB (param1, param2, specificParam1, specificParam2): print(param1,param2,specificParam1, specificParam2) myMethodA(10) myMethodB(12,13)
1 2 10 1 2 12 13
Эти два параметра можно добавить при вызове функции в функции-оболочке декоратора как части
kwargs
. Все оформленные функции автоматически передают эти два параметра в качестве аргументов ключевого слова перед вызовом:def withParams(func): def wrapper(*args, **kwargs): kwargs['param1'] = 1 kwargs['param2'] = 2 return func(*args, **kwargs) return wrapper @withParams def add(specificparam, *args, **kwargs): print(specificparam) # 3 print(args) # (4,) print(kwargs) # {'param2': 2, 'param1': 1} return specificparam + sum(args) + sum(kwargs.values()) print(add(3,4)) # 10
Вы можете отбросить часть
args
, если все, что вы будете передавать из вызова основной функции, - этоконкретные параметры для каждой функции.
Я бы рекомендовал вам пойти в старую школу и просто переписать имена, используя
functools.partial
:# module foo def func1(common_1, common_2, specific_1): pass def func2(common_1, common_2, specific_2, specific_3): pass
Тогда в другом месте (или ниже в файле, если хотите) вы можете сделать следующее:
import functools import foo common_args = (1, 'fred') foo.func1 = functools.partial(foo.func1, *common_args) foo.func2 = functools.partial(foo.func2, *common_args) # ... foo.func1('special') foo.func2('equally special', 'but different')
Похоже, что вам нужно
functools.partial
, чтобы предварительно заполнить" постоянные " параметры:>>> from functools import partial >>> def myMethodA(param1, param2, specificParm): print("myMethodA(", param1, param2, specificParm, ")") >>>> def myMethodB (param1, param2, specificParm1, specificParam2): print("myMethodB(", param1, param2, specificParm1, specificParam2, ")") >>> preMethodA = partial(myMethodA, "p1", "p2") >>> preMethodB = partial(myMethodB, "p1", "p2") >>> preMethodA(34) myMethodA( p1 p2 34 ) >>> preMethodB(8, 9) myMethodB( p1 p2 8 9 )