問題描述
自己寫了個(gè)帶參數(shù)的裝飾器,現(xiàn)在需要裝飾器隨著不同條件使用不同的參數(shù)。
問題出現(xiàn)的環(huán)境背景及自己嘗試過哪些方法
自己寫了個(gè)帶參數(shù)的裝飾器,現(xiàn)在需要裝飾器隨著不同條件使用不同的參數(shù)。如下,利用一個(gè)for循環(huán)將不通的參數(shù)傳進(jìn)裝飾器(這種時(shí)候是可以使用的):
from functools import wraps
def log(a, b, c):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('hello', str(a), str(b), str(c), func.__name__)
func(*args, **kwargs)
print('goodbye', str(a), str(b), str(c), func.__name__)
return wrapper
return decorator
a_l, b_l, c_l = [1, 2, 3], [4, 5, 6], [7, 8, 9]
l = list(range(5))
for i, j, k in zip(a_l, b_l, c_l):
@log(i, j, k)
def f():
print('ok')
f()
但是現(xiàn)在假設(shè)我的裝飾器有很多參數(shù),而且for循環(huán)內(nèi)部也有很多函數(shù),我不想每一個(gè)裝飾器都寫那么多參數(shù),于是想先給裝飾器傳好參數(shù),但是確報(bào)錯(cuò)了如下:
from functools import wraps
def log(a, b, c):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('hello', str(a), str(b), str(c), func.__name__)
func(*args, **kwargs)
print('goodbye', str(a), str(b), str(c), func.__name__)
return wrapper
return decorator
a_l, b_l, c_l = [1, 2, 3], [4, 5, 6], [7, 8, 9]
l = list(range(5))
for i, j, k in zip(a_l, b_l, c_l):
log = log(i, j, k)
@log
def f():
print('ok')
f()
#報(bào)錯(cuò)
hello 1 4 7 f
ok
goodbye 1 4 7 f
Traceback (most recent call last):
File "D:\test\ttt.py", line 22, in <module>
log = log(i, j, k)
TypeError: decorator() takes 1 positional argument but 3 were given
可以看到很怪的是第一個(gè)循環(huán)的時(shí)候是可以用的有輸出,但是到了第二個(gè)for循環(huán)的時(shí)候裝飾器傳參卻出現(xiàn)了錯(cuò)誤,不知道是為什么?請(qǐng)問到底錯(cuò)在了那里?謝謝!
更奇怪的是,我換了個(gè)函數(shù)別名竟然就可以用了。。。,代碼如下:
from functools import wraps
def log(a, b, c):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('hello', str(a), str(b), str(c), func.__name__)
func(*args, **kwargs)
print('goodbye', str(a), str(b), str(c), func.__name__)
return wrapper
return decorator
a_l, b_l, c_l = [1, 2, 3], [4, 5, 6], [7, 8, 9]
l = list(range(5))
for i, j, k in zip(a_l, b_l, c_l):
lg = log(i, j, k) # 把原來的log,換成了lg就可以正常運(yùn)行了
@lg
def f():
print('ok')
f()
請(qǐng)大神解釋到底是為什么???謝謝!
1 回答

holdtom
TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超10個(gè)贊
“帶參數(shù)的裝飾器”,這樣的描述并不準(zhǔn)確,@desc(arg)
更好的理解是函數(shù) desc
被調(diào)用,該函數(shù)返回一個(gè)裝飾器。況且你已經(jīng)知道處理方法了,只是想要知道為什么。這點(diǎn)上是一點(diǎn)就通的。
先理解一個(gè),函數(shù)允許重新賦值的
def f():
pass
f = 1
print(f) # 1
然后你對(duì)裝飾器的理解也已經(jīng)很充分了:
@log(i, j, k)
def f():
# 等價(jià)于
tmp = log(i,j,k)
@tmp
def f():
這里的原因在于,你把 log
重新賦值了,它變成了一個(gè)裝飾器,而不是一個(gè)返回裝飾器的函數(shù)。嗯,原因就是這么簡(jiǎn)單。
添加回答
舉報(bào)
0/150
提交
取消