小編寫這篇文章的主要目的,就是給大家介紹關于python裝飾器的用途方面的知識,這樣對我們以后的工作也是有一定的幫助,具體用途是什么呢?下面就給各位讀者詳細的解答下。
裝飾器自身的價值顯而易見,可以加強函數值基本功能、簡單化編碼、降低代碼冗余。
它的使用場景同樣很多,比較簡單的場景包含打印日志、統計運行時間,這類例子和用法網上已經很多了:
def time_dec(func): def wrapper(*arg): t=time.clock() res=func(*arg) print func.func_name,time.clock()-t return res return wrapper time_dec def myFunction(n): ...
再進階一些的,可以用來校驗函數傳入參數類型、線程同步、單元測試等:
parameters( (2,4,6), (5,6,11), ) def test_add(a,b,expected): assert a+b==expected
目前可以用的裝飾器可以分為如下幾類:
自定義
第三方工具包
內置
下面就分別來介紹一下。
自定義
關于自定義的裝飾器在前面已經提到了,我在開發過程中經常用到的就是日志打印、計時、數據校驗等場景,通過裝飾器可以提高代碼的簡潔性,避免重復造輪子。
除了這些基本的,也有一些比較實用的地方。
作為開發同學,肯定會遇到不同的運行環境:
開發環境
測試環境
生產環境
有時候,我們期望一個函數在不同環境下執行不同的過程,產出不同的結果,做一些環境的隔離和差異化處理。
通過裝飾器就可以很好的解決:
production_servers=[...] def production(func:Callable): def inner(*args,**kwargs): if gethostname()in production_servers: return func(*args,**kwargs) else: print('This host is not a production server,skipping function decorated with production...') return inner def development(func:Callable): def inner(*args,**kwargs): if gethostname()not in production_servers: return func(*args,**kwargs) else: print('This host is a production server,skipping function decorated with development...') return inner def sit(func:Callable): def inner(*args,**kwargs): print('Skipping function decorated with sit...') return inner production def foo(): print('Running in production,touching databases!') foo() development def foo()
print('Running in production,touching databases!') foo()
inactive def foo(): print('Running in production,touching databases!') foo()
簡單介紹一下一下子這一段源代碼。
在這兒,一開始列舉了環境個性化服務榜單,隨后各自界定了制造、研發、測試流程的裝飾器,并給同名的的變量就能夠加上對應裝飾器。
在執行代碼的過程中,這一段源代碼會首先獲取hostname,自動判斷所在環境,隨后執行對應變量。
第三方工具包
上面是根據我們在開發過程中遇到的個性化場景進行來自界定一個裝飾器。
作為一款以工具包著稱的編程語言,Python中也有很多工具包提供了一些實用的裝飾器。
以日志為例,這是每個程序員都無法繞開的。
調試程序對于大多數開發者來說是一項必不可少的工作,當我們想要知道源代碼是否按照預期的效果在執行時,我們會想到去輸出一下子局部變量與預期的進行比對。目前大多數采用的方法主要有以下幾種:
Print函數
Log日志
IDE調試器
但是這些方法有著無法忽視的弱點:
繁瑣
過度依賴工具
其中有一款不錯的開源工具PySnooper就通過裝飾器把這個問題巧妙的解決了。
PySnooper的調用方式就是通過pysnooper.snoop的方式進行使用,該裝飾器可以傳入一些參數來實現一些目的,具體如下:
參數描述:
None輸出日志到控制臺
filePath輸出到日志文件,例如'log/file.log'
prefix給調試的行加前綴,便于識別
watch查看一些非局部變量表達式的值
watch_explode展開值用以查看列表/字典的所有屬性或項
depth顯示函數調用的函數的snoop行
舉個例子:
import numpy as np import pysnooper pysnooper.snoop() def one(number): mat=[] while number: mat.append(np.random.normal(0,1)) number-=1 return mat one(3)
然后,就會給出如下輸出:
Starting var:..number=3
22:17:10.634566 call 6 def one(number):
22:17:10.634566 line 7 mat=[]
New var:.......mat=[]
22:17:10.634566 line 8 while number:
22:17:10.634566 line 9 mat.append(np.random.normal(0,1))
Modified var:..mat=[-0.4142847169210746]
22:17:10.634566 line 10 number-=1
Modified var:..number=2
22:17:10.634566 line 8 while number:
22:17:10.634566 line 9 mat.append(np.random.normal(0,1))
Modified var:..mat=[-0.4142847169210746,-0.479901983375219]
22:17:10.634566 line 10 number-=1
Modified var:..number=1
22:17:10.634566 line 8 while number:
22:17:10.634566 line 9 mat.append(np.random.normal(0,1))
Modified var:..mat=[-0.4142847169210746,-0.479901983375219,1.0491540468063252]
22:17:10.634566 line 10 number-=1
Modified var:..number=0
22:17:10.634566 line 8 while number:
22:17:10.634566 line 11 return mat
22:17:10.634566 return 11 return mat
Return value:..[-0.4142847169210746,-0.479901983375219,1.0491540468063252]
局部變量值、代碼片段、局部變量所在行號、返回結果等,這些關鍵信息都輸出了,既方便,又清晰。
內置
除了自定義和第三方工具包之外,Python還內置了很多不錯的裝飾器,例如abc.abstractmethod、asyncio.coroutine、classmethod等等。
這里著重提一個非常強大的裝飾器,能夠極大的提升Python的運行速度和效率,通過一個裝飾器能夠將Python代碼的執行速度提升上萬倍,這個裝飾器就是functools.lru_cache。
以比較知名的斐波那契數列的例子來演示一下。
由于它遞歸計算的過程中,還會用到之前計算的結果,因此會涉及較多的重復計算,下面先看一下正常計算的耗時情況。
import time as tt def fib(n): if n<=1: return n return fib(n-1)+fib(n-2) t1=tt.time() fib(30) print("Time taken:{}".format(tt.time()-t1)) #0.2073
n等于30時,耗時0.2073。
加上functools.lru_cache裝飾器再看一下:
import time as tt import functools functools.lru_cache(maxsize=5) def fib(n): if n<=1: return n return fib(n-1)+fib(n-2) t1=tt.time() fib(30) print("Time taken:{}".format(tt.time()-t1)) #1.811981e-05
耗時為1.811981e-05,足足差了4個量級,快了10000+倍!
到此為止,關于Python裝飾器作用相關知識就為大家介紹到這里了,希望可以為各位讀者帶來幫助
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127784.html
摘要:在中,裝飾器一般用來修飾函數,實現公共功能,達到代碼復用的目的。智能裝飾器上節介紹的寫法,嵌套層次較多,如果每個類似的裝飾器都用這種方法實現,還是比較費勁的腦子不夠用,也比較容易出錯。假設有一個智能裝飾器,修飾裝飾器,便可獲得同樣的能力。 在Python中,裝飾器一般用來修飾函數,實現公共功能,達到代碼復用的目的。在函數定義前加上@xxxx,然后函數就注入了某些行為,很神奇!然而,這只...
摘要:今天就結合最近的世界杯帶大家理解下裝飾器。而德國是上屆的冠軍,又是這屆奪冠熱門。裝飾器的存在是為了適用兩個場景,一個是增強被裝飾函數的行為,另一個是代碼重用。在利用語法糖,簡化賦值操作。行為良好的裝飾器可以重用,以減少代碼量。 Python 裝飾器是在面試過程高頻被問到的問題,裝飾器也是一個非常好用的特性,熟練掌握裝飾器會讓你的編程思路更加寬廣,程序也更加 pythonic。 show...
摘要:那么,這個裝飾器要怎么定義呢我們來看一下。當然了,如果大家在網絡上搜索,關于如何定義裝飾器,看到的是一個更加規范的版本。在當中,調用原函數時又,即把輸入的元祖解包再傳入。 ...
摘要:一般情況下,我們使用裝飾器提供的語法糖,來簡化上面的寫法像上面的情況,可以動態修改函數或類功能的函數就是裝飾器。本文標題為會打扮的裝飾器本文鏈接為參考資料修飾器的函數式編程中的裝飾器介紹思誠之道裝飾器入門與提高賴明星 裝飾器 我們知道,在 Python 中,我們可以像使用變量一樣使用函數: 函數可以被賦值給其他變量 函數可以被刪除 可以在函數里面再定義函數 函數可以作為參數傳遞給另外...
此篇文章主要是詳細介紹了python3常用3種裝飾器語法總結,文中根據實例編碼為大家介紹得非常詳盡,對大家學習培訓和工作具有很強的參照參考意義,需用的小伙伴可以借鑒一下 python3常用3種裝飾器語法總結 1.概述詞法 裝飾器又稱函數公式裝飾器,主要是的作用是在沒有改動原先函數的編碼前提下(函數公式自身不被改動,實現方式都不轉變),提升的另一個"裝飾設計"函數公式,...
閱讀 911·2023-01-14 11:38
閱讀 878·2023-01-14 11:04
閱讀 740·2023-01-14 10:48
閱讀 1982·2023-01-14 10:34
閱讀 942·2023-01-14 10:24
閱讀 819·2023-01-14 10:18
閱讀 499·2023-01-14 10:09
閱讀 572·2023-01-14 10:02