亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

python裝飾器傳參問題

python裝飾器傳參問題

HUWWW 2019-01-17 16:10:46
問題描述 自己寫了個帶參數的裝飾器,現在需要裝飾器隨著不同條件使用不同的參數。 問題出現的環境背景及自己嘗試過哪些方法 自己寫了個帶參數的裝飾器,現在需要裝飾器隨著不同條件使用不同的參數。如下,利用一個for循環將不通的參數傳進裝飾器(這種時候是可以使用的): 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() 但是現在假設我的裝飾器有很多參數,而且for循環內部也有很多函數,我不想每一個裝飾器都寫那么多參數,于是想先給裝飾器傳好參數,但是確報錯了如下: 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() #報錯 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 可以看到很怪的是第一個循環的時候是可以用的有輸出,但是到了第二個for循環的時候裝飾器傳參卻出現了錯誤,不知道是為什么?請問到底錯在了那里?謝謝! 更奇怪的是,我換了個函數別名竟然就可以用了。。。,代碼如下: 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就可以正常運行了 @lg def f(): print('ok') f() 請大神解釋到底是為什么???謝謝!
查看完整描述

1 回答

?
holdtom

TA貢獻1805條經驗 獲得超10個贊

“帶參數的裝飾器”,這樣的描述并不準確,@desc(arg) 更好的理解是函數 desc 被調用,該函數返回一個裝飾器。況且你已經知道處理方法了,只是想要知道為什么。這點上是一點就通的。

先理解一個,函數允許重新賦值的

def f():
    pass
f = 1
print(f)    # 1   

然后你對裝飾器的理解也已經很充分了:

@log(i, j, k)
    def f():

# 等價于
tmp = log(i,j,k)
@tmp
def f():

這里的原因在于,你把 log 重新賦值了,它變成了一個裝飾器,而不是一個返回裝飾器的函數。嗯,原因就是這么簡單。

查看完整回答
反對 回復 2019-02-12
  • 1 回答
  • 0 關注
  • 410 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號