python 自定義裝飾器 詳解

2021-08-17 09:09:56 字數 1878 閱讀 4118

先看乙個例子

def deco(func):

print("before myfunc() called.")

func()

print("after myfunc() called.")

return func

@deco

def myfunc():

print("myfunc() called.")

# myfunc = deco(myfunc) # 與上面的@deco等價

myfunc()

print("***********")

myfunc()

會發現,輸出為

before myfunc() called.

myfunc() called.

after myfunc() called.

myfunc() called.

***********

myfunc() called.

這就是說,裝飾器裡面的東西只呼叫了一次,為什麼呢?

是因為,在myfunc()函式的定義前面加一句@deco,本質上完全等價於在出現def myfunc()後,先將下面所有內容的首位址傳遞給func,然後緊接著加上一句 myfunc = deco(myfunc)。執行這句話,表示func代表了本來定義的myfunc()的函式體,同時函式myfunc()的位址傳遞給deco()函式,即 myfunc -> func,這裡就相當於myfunc的值與func的值完全相同了。然後執行裝飾器裡面的內容,最後返回給func,傳遞給myfunc。接下來在呼叫myfunc()的時候,列印輸出「myfunc() called」。第二次呼叫myfunc()函式的時候,依然只列印輸出「myfunc() called」。為什麼第二次沒有執行裝飾器裡面的內容呢?是因為,myfunc = deco(myfunc)這句話只執行了一次,而這句話,才是真正執行裝飾器裡面的內容的話。

上面的**表示,裝飾器相當於只對第一次呼叫他的函式進行了裝飾,那麼,怎麼對每次呼叫的函式都裝飾呢?接著看

def deco(func):

print("before myfunc() called.")

func(*args, **kwargs)

print("after myfunc() called.")

@deco

def myfunc(a, b):

print(a+b)

# myfunc = deco(myfunc) # 與上面的@deco等價

myfunc(1, 2)

print("***********")

myfunc(3, 4)

該**輸出結果為

before myfunc() called.

3after myfunc() called.

***********

before myfunc() called.

7after myfunc() called.

def deco(func):

func(*args, **kwargs)

@deco

def myfunc(a, b):

print(a+b)

# myfunc = deco(myfunc) # 與上面的@deco等價

myfunc(1, 2)

print("***********")

3進一步見證奇蹟!!

def deco(func):

pass

@deco

def myfunc(a, b):

print(a+b)

myfunc(1, 2)

帶引數的裝飾器,可以參見其他部落格

python 自定義裝飾器例項詳解

先看乙個例子 def deco func print before myfunc called.func print after myfunc called.return func deco def myfunc print myfunc called.myfunc deco myfunc 與上面的...

python自定義裝飾器的情況(詳解

關於函式定義的單一裝飾器 一般的通用裝飾器 多個裝飾器的使用 帶有引數的裝飾器 類裝飾器 這是裝飾器的自定義和內部機制一些初識 先強調裝飾器的要求便是 不改變原來的函式 裝飾器就乙個函式引用引數 不改變呼叫方式 我先介紹一些閉包,因為裝飾器也是基於閉包來實現的,區別閉包和裝飾器的區別就可以看外層函式...

python自定義異常例項詳解

python自定義異常例項詳解 本文通過兩種方法對python 自定義異常進行講解,第一種 建立乙個新的exception類來擁有自己的異常,第二種 raise 唯一的乙個引數指定了要被丟擲的異常 1 可以通過建立乙個新的exception類來擁有自己的異常。異常應該繼承自 exception 類,...