python三大神器===》装饰器
1.認識裝飾器
如果你經??次业牟┛?#xff0c;你已經學會了python的前兩大‘神器’(迭代器,生成器),那么什么是裝飾器呢?就如字面意義裝飾器是對某個事物(通常指函數)進行裝飾,讓其在不修改任何內部代碼的情況下增添新的功能,接下來我將一步步的解析python的裝飾器。
2.閉包
在解析裝飾器之前我們需要先了解下閉包的概念,我們先通過一段代碼了解閉包
# 定義一個函數 def test(number):# 在函數內部再定義一個函數,并且這個函數用到了外邊函數的變量,那么將這個函數以及用到的一些變量稱之為閉包def test_in(number_in):print("in test_in 函數, number_in is %d" % number_in)return number+number_in# 其實這里返回的就是閉包的結果return test_in# 給test函數賦值,這個20就是給參數number ret = test(20)# 注意這里的100其實給參數number_in print(ret(100))#注 意這里的200其實給參數number_in print(ret(200))運行結果
in test_in 函數, number_in is 100 120in test_in 函數, number_in is 200 220看完這段代碼我們不妨總結下閉包的作用:
1.函數名只是函數代碼空間的引用,當函數名賦值給一個對象的時候 就是引用傳遞
2.閉包就是一個嵌套定義的函數,在外層運行時才開始內層函數的定義,然后將內部函數的引用傳遞函數外的對象
3.內部函數和使用的外部函數提供的變量構成的整體稱為閉包
3.初識裝飾器
為什么在解釋裝飾器時要先了解閉包的概念呢?看完下面的代碼你也會就會明白
def decorate(func):def inner():return "<i>"+func()+"</i>"return inner@decorate def func():return "你好"print(func())運行結果
<i>你好</i>我們可以看出裝飾器就是在閉包的基礎上做了一些修改。
4.裝飾器普通傳參
from time import ctime, sleepdef timefun(func):
def wrapped_func(a, b):
print("%s called at %s" % (func.__name__, ctime()))
print(a, b)
func(a, b)
return wrapped_func
@timefun
def foo(a, b):
print(a+b)
foo(3,5)
sleep(2)
foo(2,4)
運行結果
foo called at Thu Aug 23 21:30:21 2018 3 5 8 foo called at Thu Aug 23 21:30:23 2018 2 4 65.裝飾器不定長傳參
from time import ctime, sleepdef timefun(func):def wrapped_func(*args, **kwargs):print("%s called at %s"%(func.__name__, ctime()))func(*args, **kwargs)return wrapped_func@timefun def foo(a, b, c):print(a+b+c)foo(1,2,3) sleep(1) foo(4,5,6)運行結果
foo called at Thu Aug 23 21:32:50 2018 6 foo called at Thu Aug 23 21:32:51 2018 15其實這里只是運用了python函數傳參時的不定長傳參的概念
6.裝飾器中的return
from time import ctime, sleepdef timefun(func):def wrapped_func():print("%s called at %s" % (func.__name__, ctime()))func()return wrapped_func@timefun def foo():print("I am foo")@timefun def getInfo():return '----hahah---'foo() sleep(2) foo()print(getInfo())運行結果
foo called at Thu Aug 23 21:36:22 2018 I am foo foo called at Thu Aug 23 21:36:24 2018 I am foo getInfo called at Thu Aug 23 21:36:24 2018 None7.裝飾器工廠(flask定義一個路由的方式)
from time import ctime, sleepdef timefun_arg(pre="hello"):def timefun(func):def wrapped_func():print("%s called at %s %s" % (func.__name__, ctime(), pre))return func()return wrapped_funcreturn timefun@timefun_arg("php") def foo():print("I am foo")@timefun_arg("python") def too():print("I am too")foo() sleep(2) foo()too() sleep(2) too()運行結果
foo called at Thu Aug 23 21:40:34 2018 php I am foo foo called at Thu Aug 23 21:40:36 2018 php I am foo too called at Thu Aug 23 21:40:36 2018 python I am too too called at Thu Aug 23 21:40:38 2018 python I am too
我們分析下裝飾器工廠裝飾過程
1. 調用timefun_arg("itcast")
? 2. 將步驟1得到的返回值,即time_fun返回, 然后time_fun(foo)
? 3. 將time_fun(foo)的結果返回,即wrapped_func
4. 讓foo = wrapped_fun,即foo現在指向wrapped_func
8.類裝飾器
class Test(object):def __init__(self, func):print("初始化中....")print("func name is %s"%func.__name__)self.__func = funcdef __call__(self):print("裝飾中......")self.__func()@Test def test():print("----test---") test()運行結果
初始化中.... func name is test 裝飾中...... ----test---我們也許會發現裝飾器中有個很特別的方法__call__(),這個方法時python內置的魔法方法,它作用就是讓類能夠向函數一樣直接被調用,接下來我會專門更新一篇python中的魔法方法,如果想要了解的朋友可以關注我
總結
? 1.裝飾器函數只有一個參數就是被裝飾的函數的應用
2.裝飾器能夠將一個函數的功能在不修改代碼的情況下進行擴展
3.在函數定義的上方@裝飾器函數名 即可直接使用裝飾器對下面的函數進行裝飾。
?
轉載于:https://www.cnblogs.com/xuchuankun/p/9526487.html
總結
以上是生活随笔為你收集整理的python三大神器===》装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站apache环境S2-057漏洞 利
- 下一篇: 数据库的使用你可能忽略了这些 (续)