繁体   English   中英

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

[英]How to use a decorator to send arguments to a function in 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 *做一些事情但仍然有特定参数的命名参数吗? 另外,如何在myMethodA中引用param1和param2

听起来你可能想要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 )

暂无
暂无

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

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