[英]How to pass a specific argument to a decorator in python
我想寫一個python函數裝飾器,測試函數的某些參數是否通過了一些標准。 例如,假設我想測試一些參數總是偶數,那么我希望能夠做這樣的事情(不是有效的python代碼)
def ensure_even( n ) :
def decorator( function ) :
@functools.wraps( function )
def wrapper(*args, **kwargs):
assert(n % 2 == 0)
return function(*args, **kwargs)
return wrapper
return decorator
@ensure_even(arg2)
def foo(arg1, arg2, arg3) : pass
@ensure_even(arg3)
def bar(arg1, arg2, arg3) : pass
但我無法想象如何實現上述目標。 有沒有辦法將特定參數傳遞給裝飾器? (比如arg2 for foo和arg3 for bar in)
謝謝!
你可以這樣做:
def ensure_even(argnum):
def fdec(func):
def f(*args, **kwargs):
assert(args[argnum] % 2 == 0) #or assert(not args[argnum] % 2)
return func(*args, **kwargs)
return f
return fdec
那么:
@ensure_even(1) #2nd argument must be even
def test(arg1, arg2):
print(arg2)
test(1,2) #succeeds
test(1,3) #fails
我之前的回答錯過了你的問題。
這是一個更長的解決方案:
def ensure_even(*argvars):
def fdec(func):
def f(*args,**kwargs):
for argvar in argvars:
try:
assert(not args[func.func_code.co_varnames.index(argvar)] % 2)
except IndexError:
assert(not kwargs[argvar] % 2)
return func(*args,**kwargs)
return f
return fdec
這是用法:
@ensure_even('a','b')
def both_even(a,b):
print a,b
@ensure_even('even')
def first_even(even, arg2):
print even, arg2
both_even(2,2)
first_even(2,3)
both_even(2,1) #fails
雖然我不確定它是否適用於所有情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.