1. 程式人生 > >Python隨心記--裝飾器

Python隨心記--裝飾器

裝飾器
本質就是函式,功能是為其他函式新增附加功能
原則是:不修改被修飾函式的原始碼
不修改被修飾函式的呼叫方式
統計函式的執行時間 
import time
def cal(l):
    start_time = time.time()
    res = 0
    for i in l:
        time.sleep(0.1)
        res += i
    stop_time = time.time()
    print('函式的執行時間是%s秒' %(stop_time - start_time))
    return res
print(cal(range(10)))
加上裝飾器方法 統計函式的執行時間
import time
def timmer(func):
    def wapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print('函式的執行時間是%s秒' %(stop_time - start_time))
        return res
    return wapper
@timmer
def cal(l): res = 0 for i in l: time.sleep(0.1) res += i return res print(cal(range(10)))
裝飾器的知識儲備
裝飾器 = 高階函式+函式巢狀+閉包
高階函式
函式接收的引數是一個函式名
函式的返回值是一個函式名
滿足上述任意條件一個都是高階函式
 
 
 
def foo():
    print('你好啊林師傅')
def test(func):   #高階函式
    print(func)
    func()
print(test(foo))
 
 
 
import time
def foo():
    print('你好啊林師傅')
def test(func):
    print(func)
    start_time = time.time()
    func()
    stop_time = time.time()
    print('函式的執行時間是%s秒' % (stop_time - start_time))
print(test(foo))
注:以上多運行了一次foo函式  

#高階函式滿足不了裝飾器
 
 
 
import time
def foo():
    time.sleep(1)
    print('來自foo')
#不修改foo程式碼
#不修改foo呼叫方式
def timer(func):
    start_time = time.time()
    func()
    stop_time = time.time()
    print('函式的執行時間是%s秒' % (stop_time - start_time))
    return func
foo = timer(foo)
print(foo())
 
函式巢狀:函式裡面定義一個函式
def father(name):
    print('from father %s' %name)
    def son():
        print('from son')
        def grandson():
            print('from grandson')
        grandson()
    son()
father('大佬')
def father(name):
    print('from father %s' %name)
    def son():
        print('from son')
    print(locals())
father('大佬')
函式巢狀及作用域
def father(name):
    def son():
        print('from son %s' %name)
    son()
father('大佬')
def father(name):
    def son():
        name = '小豆芽'
        print('from son %s' %name)
    son()
father('大佬')

函式閉包裝飾器基本實現
裝飾器的框架
import time
def itmmer(func):
    def wrapper():
        strat_time = time.time()
        func()   #執行test函式
        stop_time = time.time()
        print('函式的執行時間是%s秒' % (stop_time - strat_time))
    return wrapper
def test():
    time.sleep(3)
    print('test函式執行完畢')
test = itmmer(test)#返回的是wrapper的地址
test()

 

#   @timmer  相當於 test = itmmer(test)  語法糖
import time
def itmmer(func):
    def wrapper():
        strat_time = time.time()
        func()   #執行test函式
        stop_time = time.time()
        print('函式的執行時間是%s秒' % (stop_time - strat_time))
    return wrapper
@itmmer
def test():
    time.sleep(3)
    print('test函式執行完畢')
test()
這裡新增test返回值,,解決函式最後返回的None
import time
def itmmer(func):
    def wrapper():
        strat_time = time.time()
        res = func()   #執行test函式
        stop_time = time.time()
        print('函式的執行時間是%s秒' % (stop_time - strat_time))
        return res
    return wrapper
@itmmer
def test():
    time.sleep(1)
    print('test函式執行完畢')
    return '這裡新增test返回值,,解決函式最後返回的None'
res = test()   #這裡會最後會返回一個None
print(res)

帶引數
import time
def itmmer(func):
    def wrapper(name,age):
        strat_time = time.time()
        res = func(name,age)   #執行test函式
        stop_time = time.time()
        print('函式的執行時間是%s秒' % (stop_time - strat_time))
        return res
    return wrapper
@itmmer
def test(name,age):
    time.sleep(1)
    print('test函式執行完畢,名字是%s,年齡是%s' %(name,age))
    return '這裡新增test返回值,,解決函式最後返回的None'
test('ss',20)
帶引數 修改為可變引數
import time
def itmmer(func):
    def wrapper(*args,**kwargs):
        strat_time = time.time()
        res = func(*args,**kwargs)   #執行test函式
        stop_time = time.time()
        print('函式的執行時間是%s秒' % (stop_time - strat_time))
        return res
    return wrapper
@itmmer
def test(name,age):
    time.sleep(1)
    print('test函式執行完畢,名字是【%s】,年齡是【%s】' %(name,age))
    return '這裡新增test返回值,,解決函式最後返回的None'
test('ss',20)
可變引數 *args,**kwargs 傳參例項
def test2(name,age,gender):
    print(name)
    print(age)
    print(gender)
def test1(*args,**kwargs):
    test2(*args,**kwargs)   #test2(*('alex',18,'male','x','y'),**{})