2017-07-30 69 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) 
相關問題