導航:首頁 > 編程語言 > python裝飾器

python裝飾器

發布時間:2022-01-20 19:01:25

① 什麼是python裝飾器


所謂裝飾器就是把函數包裝一下,為函數添加一些附加功能,裝飾器就是一個函數,參數為被包裝的函數,返回包裝後的函數:你可以試下:

defd(fp):
def_d(*arg,**karg):
print"dosthbeforefp.."
r=fp(*arg,**karg)
print"dosthafterfp.."
returnr
return_d
@d
deff():
print"callf"
#上面使用@d來表示裝飾器和下面是一個意思
#f=d(f)
f()#調用f



② python裝飾器是什麼意思

裝飾器是程序開發中經常會用到的一個功能,用好了裝飾器,開發效率如虎添翼,所以這也是Python面試中必問的問題,但對於好多小白來講,這個功能 有點繞,自學時直接繞過去了,然後面試問到了就掛了,因為裝飾器是程序開發的基礎知識,這個都 不會,別跟人家說你會Python, 看了下面的文章,保證你學會裝飾器。

1、先明白這段代碼

####第一波####

deffoo():

print'foo'

foo#表示是函數

foo()#表示執行foo函數

####第二波####

deffoo():

print'foo'

foo=lambdax:x+1

foo()#執行下面的lambda表達式,而不再是原來的foo函數,因為函數foo被重新定義了

2、需求來了

初創公司有N個業務部門,1個基礎平台部門,基礎平台負責提供底層的功能,如:資料庫操作、redis調用、監控API等功能。業務部門使用基礎功能時,只需調用基礎平台提供的功能即可。如下:

###############基礎平台提供的功能如下###############

deff1():

print'f1'

deff2():

print'f2'

deff3():

print'f3'

deff4():

print'f4'

###############業務部門A調用基礎平台提供的功能###############

f1()

f2()

f3()

f4()

###############業務部門B調用基礎平台提供的功能###############

f1()

f2()

f3()

f4()

目前公司有條不紊的進行著,但是,以前基礎平台的開發人員在寫代碼時候沒有關注驗證相關的問題,即:基礎平台的提供的功能可以被任何人使用。現在需要對基礎平台的所有功能進行重構,為平台提供的所有功能添加驗證機制,即:執行功能前,先進行驗證。

老大把工作交給 Low B,他是這么做的:

跟每個業務部門交涉,每個業務部門自己寫代碼,調用基礎平台的功能之前先驗證。誒,這樣一來基礎平台就不需要做任何修改了。

當天Low B 被開除了…

老大把工作交給 Low BB,他是這么做的:

###############基礎平台提供的功能如下###############

deff1():

#驗證1

#驗證2

#驗證3

print'f1'

deff2():

#驗證1

#驗證2

#驗證3

print'f2'

deff3():

#驗證1

#驗證2

#驗證3

print'f3'

deff4():

#驗證1

#驗證2

#驗證3

print'f4'

###############業務部門不變###############

###業務部門A調用基礎平台提供的功能###

f1()

f2()

f3()

f4()

###業務部門B調用基礎平台提供的功能###

f1()

f2()

f3()

f4()

過了一周 Low BB 被開除了…

老大把工作交給 Low BBB,他是這么做的:

只對基礎平台的代碼進行重構,其他業務部門無需做任何修改

###############基礎平台提供的功能如下###############

defcheck_login():

#驗證1

#驗證2

#驗證3

pass

deff1():

check_login()

print'f1'

deff2():

check_login()

print'f2'

deff3():

check_login()

print'f3'

deff4():

check_login()

print'f4'

老大看了下Low BBB 的實現,嘴角漏出了一絲的欣慰的笑,語重心長的跟Low BBB聊了個天:

老大說:

寫代碼要遵循開發封閉原則,雖然在這個原則是用的面向對象開發,但是也適用於函數式編程,簡單來說,它規定已經實現的功能代碼不允許被修改,但可以被擴展,即:

③ Python裝飾器報錯,找不到名字

定義語句必須出現在調用語句之前。

④ python 某一函數上面有多個裝飾器

首先十分不推薦這種做法, 會令程序難以維護.
其次, 多個裝飾器是按照裝飾器的順序進行執行的.
如果你編寫過裝飾器, 你就應該知道, 其實裝飾器就是把函數的名字傳入進去, 在執行函數之前, 進行一些提前的處理.
例如下面這段代碼, 自定義的裝飾器
def add_schedid(handler_func):
"""
@handler_func: 請求處理函數
"""
@functools.wraps(handler_func)
def wrapper(self, *args, **kwargs):
"""
wrapper
"""
# handler_func就是所裝飾的函數,可以在這里做一些真正函數執行前所需的處理,
handler_func(self, *args, **kwargs)

return wrapper

裝飾器本身就是一個函數, 將所裝飾的函數, 作為一個參數傳進來, 然後在執行這個函數之前, 進行一個處理,這就是裝飾器. 所以和正常函數執行順序是一樣的..

⑤ 什麼時候會用到python裝飾器

裝飾器其實也就是一個函數,一個用來包裝函數的函數,返回一個修改之後的函數對象。經常被用於有切面需求的場景,較為經典的有插入日誌、
性能測試、事務處理等。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量函數中與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝
飾器的作用就是為已經存在的對象添加額外的功能。

⑥ python有關裝飾器的問題

1,遞歸的終止點,即遞歸函數的出口

2,不斷的遞歸調用自身

3,遞歸函數主體內容,即遞歸函數需要做的事情

⑦ python裝飾器的作用和功能

裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。它經常用於有切面需求的場景,比如:插入日誌、性能測試、事務處理、緩存、許可權校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能

⑧ python裝飾器有什麼用

先來個形象比方

內褲可以用來遮羞,但是到了冬天它沒法為我們防風禦寒,聰明的人們發明了長褲,有了長褲後寶寶再也不冷了,裝飾器就像我們這里說的長褲,在不影響內褲作用的前提下,給我們的身子提供了保暖的功效。

再回到我們的主題

裝飾器本質上是一個Python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。它經常用於有切面需求的場景,比如:插入日誌、性能測試、事務處理、緩存、許可權校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離出大量與函數功能本身無關的雷同代碼並繼續重用。概括的講,裝飾器的作用就是為已經存在的對象添加額外的功能。

先來看一個簡單例子:

def foo():
print('i am foo')

現在有一個新的需求,希望可以記錄下函數的執行日誌,於是在代碼中添加日誌代碼:

def foo():
print('i am foo')
logging.info("foo is running")

bar()、bar2()也有類似的需求,怎麼做?再寫一個logging在bar函數里?這樣就造成大量雷同的代碼,為了減少重復寫代碼,我們可以這樣做,重新定義一個函數:專門處理日誌 ,日誌處理完之後再執行真正的業務代碼

def use_logging(func):
logging.warn("%s is running" % func.__name__)
func()def bar():
print('i am bar')use_logging(bar)

邏輯上不難理解,
但是這樣的話,我們每次都要將一個函數作為參數傳遞給use_logging函數。而且這種方式已經破壞了原有的代碼邏輯結構,之前執行業務邏輯時,執行運行bar(),但是現在不得不改成use_logging(bar)。那麼有沒有更好的方式的呢?當然有,答案就是裝飾器。


簡單裝飾器
def use_logging(func):

def wrapper(*args, **kwargs):
logging.warn("%s is running" % func.__name__)
return func(*args, **kwargs)
return wrapperdef bar():
print('i am bar')bar = use_logging(bar)bar()

函數use_logging就是裝飾器,它把執行真正業務方法的func包裹在函數裡面,看起來像bar被use_logging裝飾了。在這個例子中,函數進入和退出時
,被稱為一個橫切面(Aspect),這種編程方式被稱為面向切面的編程(Aspect-Oriented Programming)。

@符號是裝飾器的語法糖,在定義函數的時候使用,避免再一次賦值操作


def use_logging(func):

def wrapper(*args, **kwargs):
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper@use_loggingdef foo():
print("i am foo")@use_loggingdef bar():
print("i am bar")bar()

如上所示,這樣我們就可以省去bar =
use_logging(bar)這一句了,直接調用bar()即可得到想要的結果。如果我們有其他的類似函數,我們可以繼續調用裝飾器來修飾函數,而不用重復修改函數或者增加新的封裝。這樣,我們就提高了程序的可重復利用性,並增加了程序的可讀性。

裝飾器在Python使用如此方便都要歸因於Python的函數能像普通的對象一樣能作為參數傳遞給其他函數,可以被賦值給其他變數,可以作為返回值,可以被定義在另外一個函數內。


帶參數的裝飾器

裝飾器還有更大的靈活性,例如帶參數的裝飾器:在上面的裝飾器調用中,比如@use_logging,該裝飾器唯一的參數就是執行業務的函數。裝飾器的語法允許我們在調用時,提供其它參數,比如@decorator(a)。這樣,就為裝飾器的編寫和使用提供了更大的靈活性。

def use_logging(level):
def decorator(func):
def wrapper(*args, **kwargs):
if level == "warn":
logging.warn("%s is running" % func.__name__)
return func(*args)
return wrapper

return decorator@use_logging(level="warn")def foo(name='foo'):
print("i am %s" % name)foo()

上面的use_logging是允許帶參數的裝飾器。它實際上是對原有裝飾器的一個函數封裝,並返回一個裝飾器。我們可以將它理解為一個含有參數的閉包。當我
們使用@use_logging(level="warn")調用的時候,Python能夠發現這一層的封裝,並把參數傳遞到裝飾器的環境中。


類裝飾器

再來看看類裝飾器,相比函數裝飾器,類裝飾器具有靈活度大、高內聚、封裝性等優點。使用類裝飾器還可以依靠類內部的\_\_call\_\_方法,當使用 @ 形式將裝飾器附加到函數上時,就會調用此方法。


class Foo(object):
def __init__(self, func):
self._func = func

def __call__(self):
print ('class decorator runing')
self._func()
print ('class decorator ending')

@Foo
def bar():
print ('bar')

bar()

functools.wraps

使用裝飾器極大地復用了代碼,但是他有一個缺點就是原函數的元信息不見了,比如函數的docstring、__name__、參數列表,先看例子:

裝飾器

def logged(func):
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging

函數

@loggeddef f(x):
"""does some math"""
return x + x * x

該函數完成等價於:


def f(x):
"""does some math"""
return x + x * xf = logged(f)

不難發現,函數f被with_logging取代了,當然它的docstring,__name__就是變成了with_logging函數的信息了。

print f.__name__ # prints 'with_logging'print f.__doc__ # prints None

這個問題就比較嚴重的,好在我們有functools.wraps,wraps本身也是一個裝飾器,它能把原函數的元信息拷貝到裝飾器函數中,這使得裝飾器函數也有和原函數一樣的元信息了。

from functools import wrapsdef logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging@loggeddef f(x):
"""does some math"""
return x + x * xprint f.__name__ # prints 'f'print f.__doc__ # prints 'does some math'

內置裝飾器

@staticmathod、@classmethod、@property

裝飾器的順序
@a@b@cdef f ():

等效於


f = a(b(c(f)))

⑨ Python中的裝飾器是作什麼用的在哪可以找到這些教程。

裝飾器是Python語法糖的一種,可以用來簡化代碼,讓代碼更加簡潔
裝飾器的作用是在不改變函數代碼和調用方式的前提下,為已有函數功能添加額外的功能。
可以通過裝飾器對代碼實現許可權管理,用戶驗證,日誌管理,緩存判斷,參數檢查等等。
以上內容均來自傳智播客,自己可以去搜搜,很多課。

閱讀全文

與python裝飾器相關的資料

熱點內容
prom文件夾 瀏覽:726
不規則土方的演算法 瀏覽:209
tor加密貨幣網站 瀏覽:449
linux轉ansi 瀏覽:736
網站源碼怎麼查 瀏覽:687
高cpu雲伺服器 瀏覽:365
androidwebrtcaecm 瀏覽:981
阿里雲部署java 瀏覽:636
雲是不是就是個大的伺服器 瀏覽:581
如何建立linux日誌管理伺服器 瀏覽:772
悟空頭圖標是什麼APP 瀏覽:555
linuxandroid虛擬機 瀏覽:281
ps李濤pdf 瀏覽:638
linuxfork線程 瀏覽:97
易語言編譯改名 瀏覽:723
阿里伺服器都提供什麼 瀏覽:756
cf打開伺服器接不上怎麼辦 瀏覽:901
linux下more命令 瀏覽:402
des演算法運算位數 瀏覽:375
珠海建行貸款解壓 瀏覽:635