2017-07-30 76 views
3

我有一组函数在python中获取相同的2个参数+其他参数。如何使用装饰器将参数发送到Python中的函数

def myMethodA (param1, param2, specificParm) 
    do code 

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

我减弱创建一个装饰器替换成需要通过推动参数调用函数之前与第2个参数来调用:

@withParams() 
def myMethodA (specificParam) 
     do code 

但是,如果我省略了参数,那么装饰器如果我离开他们,那么调用者也需要指定他们。

无论如何要解决这个问题? 我可以使用args *做些什么,但仍然为specificParam命名参数? 另外,如何在myMethodA中引用param1和param2

+0

看看'functools.partial'也 –

回答

1

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

这看起来不错,但如果签名是myMethodA(param1,param2,specificParam),'myMethodA(10)'如何工作? ? –

+0

这两个选项都可以解决问题,并且都可以使用。我选择了部分,因为语法更清洁 –

+0

这就是装饰者所做的。为函数名称分配一个新的函数对象。在这种情况下,新函数会减少两个参数,并使用两个提供的参数以及任何其他参数调用原始函数。 –

0

当您在装饰器的包装函数中调用函数作为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部分每个功能。

+1

这是我跳,但不是装饰只是一个函数调用?如何将两个参数添加到不期望它们的函数会起作用?我期望得到类似'方法预期1参数,但3提供 –

+0

而且,这样,我不能引用myMethodA中的param1和param2,因为它们没有定义。 –

+0

@EranWitkon你可以在你的函数中使用'* args'来与其他参数一起收集'param2'和'param2'。查看更新。 –

0

我建议你去老同学,并且只使用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') 
0

听起来像是你需要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) 
相关问题