简体   繁体   English

如何使用装饰器向python中的函数发送参数

[英]How to use a decorator to send arguments to a function in python

I have a set of functions in python that gets the same 2 parameters + other parameters. 我在python中有一组函数,它们获得相同的2个参数+其他参数。

def myMethodA (param1, param2, specificParm)
    do code

 def myMethodB (param1, param2, specificParm1 specificParam2)
    do code

I waned to create a decorator that replace the need to call with the first 2 parameters by pushing the parameters before calling the function: 我匆匆创建了一个装饰器,通过在调用函数之前按下参数来替换前2个参数调用的需要:

@withParams()
def myMethodA (specificParam)
        do code

But if I omit the parameters then the decorator can't call it either and if I leave them then the caller need to specify them as well. 但是如果我省略了参数,那么装饰器也无法调用它,如果我离开它们,那么调用者也需要指定它们。

anyway to solve this? 无论如何要解决这个问题? Can I do something with args* but still have named parameters for specificParam? 我可以用args *做一些事情但仍然有特定参数的命名参数吗? Also, How can I reference param1 and param2 inside myMethodA 另外,如何在myMethodA中引用param1和param2

It sounds like you may want functools.partial . 听起来你可能想要functools.partial It returns a new function with some parameters already specified: 它返回一个新函数,其中已经指定了一些参数:

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 

You can add those two parameters when you call the function in the decorator's wrapper function as part of the kwargs . 当您在装饰器的包装函数中调用函数作为kwargs一部分时,可以添加这两个参数。 All decorated functions will automatically have those two parameters passed as keyword arguments before making the call: 在进行调用之前,所有修饰函数都会自动将这两个参数作为关键字参数传递:

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

You can drop the args part if all you'll be passing from the main function call are the specific parameters for each function. 如果您从主函数调用传递的所有内容都是每个函数的特定参数 ,则可以删除args部分。

I'd recommend you go old school, and just reassign the names using functools.partial : 我建议你去老学校,然后使用functools.partial重新分配名字:

# module foo

def func1(common_1, common_2, specific_1):
    pass

def func2(common_1, common_2, specific_2, specific_3):
    pass

Then elsewhere (or lower in the file, if you like) you can do this: 然后在其他地方(或文件中较低的,如果你愿意)你可以这样做:

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

Sounds like you need functools.partial , to pre-populate the "constant" parameters: 听起来你需要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 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM