<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
名稱空間與作用域
函數物件:
函數的巢狀定義:在函數內定義函數
閉包函數:父函數的返回值為一個函數,被返回的函數呼叫了父函數的區域性變數,且該函數可以在父函數外部執行
裝飾器:
裝飾器:定義一個為其他函數新增功能的函數
為什麼要使用裝飾器?
裝飾器實現:
需求:不修改原始碼,計算程式碼執行時間
原始碼:
import time def func0(x): time.sleep(1) print(x) func0(0) # 方案一:實現了計算程式碼執行時間的功能,但修改了原始碼,不符合要求 def func1(x): start = time.time() time.sleep(1) print(x) end = time.time() print('方案一 執行時間:{}'.format(end - start)) func1(1) # 方案二:滿足要求,但程式碼不具備重用性 start = time.time() func0(2) end = time.time() print('方案二 執行時間:{}'.format(end - start)) # 方案三:將方案二封裝為函數,但修改了函數的呼叫方式,不符合要求 def wrapper(): start = time.time() func0(3) end = time.time() print('方案三 執行時間:{}'.format(end - start)) wrapper() # 方案四:不修改原函數的呼叫方式 def wrapper(x): start = time.time() func0(x) end = time.time() print('方案四 執行時間:{}'.format(end - start)) wrapper(4) # 方案五:方案四引數被寫死,優化方案四 def wrapper(*args, **kwargs): start = time.time() func0(*args, **kwargs) end = time.time() print('方案五 執行時間:{}'.format(end - start)) wrapper(5) # 方案六:方案五函數被寫死,優化方案五,但修改了原始碼的呼叫方式 def outter(a): def wrapper(*args, **kwargs): start = time.time() a(*args, **kwargs) end = time.time() print('方案六 執行時間:{}'.format(end - start)) return wrapper f = outter(func0) f(6) # 方案七:優化方案六(outter即為裝飾器,用於裝飾func0) def outter(a): def wrapper(*args, **kwargs): start = time.time() a(*args, **kwargs) end = time.time() print('方案七 執行時間:{}'.format(end - start)) return wrapper func0 = outter(func0) # 偷樑換柱,呼叫者無感知 func0(7)
執行結果:
0
1
方案一 執行時間:1.001857042312622
2
方案二 執行時間:1.0040733814239502
3
方案三 執行時間:1.0017154216766357
4
方案四 執行時間:1.007995367050171
5
方案五 執行時間:1.0145602226257324
6
方案六 執行時間:1.0046615600585938
7
方案七 執行時間:1.0094060897827148
# 不使用語法糖 import time def func0(x): time.sleep(1) print(x) # func0(0) def outter(a): def wrapper(*args, **kwargs): start = time.time() a(*args, **kwargs) end = time.time() print('執行時間:{}'.format(end - start)) return wrapper func0 = outter(func0) func0('hello') # 使用語法糖 import time def outter(a): def wrapper(*args, **kwargs): start = time.time() a(*args, **kwargs) end = time.time() print('執行時間:{}'.format(end - start)) return wrapper @outter # 語法糖,等價於該行func0 = outter(func0) def func0(x): time.sleep(1) print(x) func0('hello') print(func0.__name__)
執行結果:
hello
執行時間:1.0050427913665771
wrapper
# 裝飾器模板 def decorator_name(x): def wrapper(*args, **kwargs): # ...新新增的功能... # 下為呼叫原函數的格式 x(*args, **kwargs) return wrapper @decorator_name def func_name(): pass
擴充套件:真正實現偷樑換柱,呼叫者無感知
# 不使用裝飾器 import time def func0(x): time.sleep(1) print(x) func0('hello') print(func0.__name__) # 檢視函數名 print(help(func0)) # 檢視幫助資訊(主要為註釋內容)
執行結果:
hello
func0
Help on function func0 in module main:func0(x)
這是函數None
使用裝飾器:
import time def outter(a): def wrapper(*args, **kwargs): '''這是裝飾器''' start = time.time() a(*args, **kwargs) end = time.time() print('執行時間:{}'.format(end - start)) return wrapper @outter # func0 = outter(func0) def func0(x): '''這是函數''' time.sleep(1) print(x) func0('hello') print(func0.__name__) print(help(func0))
執行結果:
hello
執行時間:1.011878490447998
wrapper
Help on function wrapper in module main:wrapper(*args, **kwargs)
這是裝飾器None
嘔吼,露餡了
import time def outter(a): def wrapper(*args, **kwargs): '''這是裝飾器''' start = time.time() a(*args, **kwargs) end = time.time() print('執行時間:{}'.format(end - start)) wrapper.__name__ = a.__name__ wrapper.__doc__ = a.__doc__ return wrapper @outter # func0 = outter(func0) def func0(x): '''這是函數''' time.sleep(1) print(x) func0('hello') print(func0.__name__) print(help(func0))
執行結果:
hello
執行時間:1.0030155181884766
func0
Help on function func0 in module main:func0(*args, **kwargs)
這是函數None
但是,函數有很多屬性和方法,一個一個手動修改過於麻煩,甚至可能會遺漏,但python也提供瞭解決方法
import time from functools import wraps def outter(a): @wraps(a) def wrapper(*args, **kwargs): '''這是裝飾器''' start = time.time() a(*args, **kwargs) end = time.time() print('執行時間:{}'.format(end - start)) # wrapper.__name__ = a.__name__ # wrapper.__doc__ = a.__doc__ return wrapper @outter # func0 = outter(func0) def func0(x): '''這是函數''' time.sleep(1) print(x) func0('hello') print(func0.__name__) print(help(func0))
執行結果:
hello
執行時間:1.0114128589630127
func0
Help on function func0 in module main:func0(x)
這是函數None
def outter(db_type): # 裝飾器auth def auth(x): def wrapper(*args, **kwargs): if db_type == 'file': name = input('請輸入姓名:') passwd = input('請輸入密碼:') if name == 'zhangsan' and passwd == '123': x(*args, **kwargs) print('基於檔案認證') else: print('使用者名稱或密碼錯誤,認證失敗') elif db_type == 'mysql': x(*args, **kwargs) print('基於資料庫認證') else: print('未知認證方式,不支援') return wrapper return auth # 函數 auth = outter(db_type='file') @auth def file(): print('hello') auth = outter(db_type='mysql') @auth def mysql(): print('world') msg = input('請選擇認證方式(1=file|2=mysql):').strip() if msg =='1': file() elif msg == '2': mysql() else: print('不支援')
def outter(db_type): # 裝飾器auth def auth(x): def wrapper(*args, **kwargs): if db_type == 'file': name = input('請輸入姓名:') passwd = input('請輸入密碼:') if name == 'zhangsan' and passwd == '123': x(*args, **kwargs) print('基於檔案認證') else: print('使用者名稱或密碼錯誤,認證失敗') elif db_type == 'mysql': x(*args, **kwargs) print('基於資料庫認證') else: print('未知認證方式,不支援') return wrapper return auth # 函數 # auth = outter(db_type='file') # @auth @outter(db_type='file') def file(): print('hello') # auth = outter(db_type='mysql') # @auth @outter(db_type='mysql') def mysql(): print('world') msg = input('請選擇認證方式(1=file|2=mysql):').strip() if msg =='1': file() elif msg == '2': mysql() else: print('不支援')
# 有參裝飾器模板 def out_decorator_name(x,y,z): def decorator_name(a): def wrapper(*args, **kwargs): # ...新新增的功能... # 下為呼叫原函數的格式 a(*args, **kwargs) return wrapper return decorator_name @out_decorator_name(x,y,z=1) def func_name(): pass
到此這篇關於深入瞭解python裝飾器的文章就介紹到這了,更多相關python裝飾器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45