python3 如何给装饰器传递参数
【引子】
之前寫過一篇文章用來講解裝飾器(https://www.cnblogs.com/JiangLe/p/9309330.html) 、那篇文章的定位是入門級的
所以也就沒有講過多的高級主題,決定在這里講一下如果為裝飾器傳遞參數
?
【目標】
我們有兩個函數“add_fun”、“add” 其中“add_fun”已經過時、如果用戶有調用這個函數的話就提示它“add_fun”已經過時并且引導
它去調用“add”函數
?
【add\add_fun函數的定義】
def add_fun(x,y):"""實現兩個數相加、并返回合"""return x+ydef add(x,y):"""實現兩個數相加、并返回合"""return x+y?
【通過裝飾器引導調用add_fun的用戶去調用add】
def deprecated(fun,new_fun_name):"""deprecated函數會返回一個叫inner的函數、inner函數會返回fun調用的結果,與直接調用fun得到值不同的是inner會先打印一行提示表明fun已經過時"""def inner(x,y):print("{fun.__name__} 函數已經過時 請使用{new_fun_name}".format(fun=fun,new_fun_name=new_fun_name))return fun(x,y)return innerdef add_fun(x,y):"""實現兩個數相加、并返回合"""return x+yadd_fun = deprecated(add_fun,'add')def add(x,y):"""實現兩個數相加、并返回合"""return x+y if __name__=="__main__":print(add_fun(1,1))調用時的輸出如下:
python3 dc.py add_fun 函數已經過時 請使用add 2?
【難道為裝飾器增加參數就這么的簡單】
仔細的你可能已經發現了、我們在上面的代碼里并沒有用裝飾器的語法糖衣、而是通過函數調用的方式來包裝的add_fun方法
add_fun = deprecated(add_fun,'add')機智的你應該想到了@deprecated('add') 這樣去裝飾add_fun應該也能成吧!于是代碼如下(關鍵代碼)
@deprecated('add') def add_fun(x,y):"""實現兩個數相加、并返回合"""return x+y當你調用時會發現完全不是你想要的那樣、
python3 dc.py Traceback (most recent call last):File "dc.py", line 12, in <module>@deprecated('add') TypeError: deprecated() missing 1 required positional argument: 'new_fun_name'事實上目前語法糖衣只解決了最簡單的情況、如果你要給@寫法 指定參數還要另尋它法。
?
【真理簡潔而有力】
linux的世界里有句話“一切皆文件”,python的世界里也有一句話“一切皆對象”; 但是關鍵不是會“背”,而是“領悟”。
一個經典的糖衣格式是這樣的
@decorate def fun():pass請仔細看一下不難發現@后面直接是對象名、由python的數據模式可知、對象名只是一個對象的標識;也就是說@后面是一個對象!對象可以
是已經定義好的,也可以是調用才生成。明白這一層道理之后事情就比較好辦了,我們只要在調用時生成“裝飾”對象就可以了,因為要調用
所以就給了我們傳遞參數的機會。
?
【觸摸真理一】
? 用調用時生成的對象用作裝飾器
def deprecated(new_fun_name):"""derepcated 裝飾器把函數標記為過時"""def warpper(fun):""""""def inner(*args):print("{0} 函數已經過時 請使用 {1}".format(fun.__name__,new_fun_name))return fun(*args)return innerreturn warpperdecorator = deprecated('add') # 特意把這一步單獨分離出來、用于說明什么叫調用時創建的對象用作做裝飾器 @decorator # 特意把這一步單獨分離出來、用于說明什么叫調用時創建的對象用作做裝飾器 def add_fun(x,y):"""實現兩個數相加、并返回合"""return x+ydef add(x,y):"""實現兩個數相加、并返回合"""return x+y if __name__=="__main__":print(add_fun(1,1))?
【觸摸真理二】
與語法糖衣結合、完成傳遞參數的目的
def deprecated(new_fun_name):"""derepcated 裝飾器把函數標記為過時"""def warpper(fun):""""""def inner(*args):print("{0} 函數已經過時 請使用 {1}".format(fun.__name__,new_fun_name))return fun(*args)return innerreturn warpper@deprecated('add') def add_fun(x,y):"""實現兩個數相加、并返回合"""return x+ydef add(x,y):"""實現兩個數相加、并返回合"""return x+y if __name__=="__main__":print(add_fun(1,1))調用時輸出如下
python3 dc.py add_fun 函數已經過時 請使用 add 2?
?
總結:
如果只能用一名話概括python我想對簡潔的應該是“一切皆對象”了吧。
?
轉載于:https://www.cnblogs.com/JiangLe/p/9309566.html
總結
以上是生活随笔為你收集整理的python3 如何给装饰器传递参数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot thymeleaf
- 下一篇: 本地IDC机房数据库容灾解决方案