閉包和裝飾器,兩者關係以及裝飾器工廠的使用

2022-08-04 18:36:11 字數 3402 閱讀 8578

1. 閉包的概念

--- in test1 func----

140212571149040

140212571149040

--- in test1 func----

2. 閉包

# 定義乙個函式

def test(number):

# 在函式內部再定義乙個函式,並且這個函式用到了外邊函式的變數,那麼將這個函式以及用到的一些變數稱之為閉包

def test_in(number_in):

print("in test_in 函式, number_in is %d" % number_in)

return number+number_in

# 其實這裡返回的就是閉包的結果

return test_in

# 給test函式賦值,這個20就是給引數number

ret = test(20)

# 注意這裡的100其實給引數number_in

print(ret(100))

#注 意這裡的200其實給引數number_in

print(ret(200))

3. 什麼是閉包?

1. 有這樣的一種形象的比喻裝飾器是什麼?

2. 裝飾器的兩種實現方式

# 定義函式:完成包裹資料

def makebold(fn):

return "" + fn() + ""

# 定義函式:完成包裹資料

def makeitalic(fn):

return "" + fn() + ""

'''

@makebold等價於test1 = makebold(test1)

1. 將整個test1 = makeblod(test1)從右到左執行

2. 先將test1賦值給makeblod中的引數fn,test1和fn兩個物件指向同乙個函式

7. 因此而達到不更改原**的,在原有基礎上增加功能

'''@makebold

def test1():

return "hello world-1"

print(test1())

@makeitalic # 等價於test2 = makebold(test2)

def test2():

return "hello world-2"

print(test2())

列印結果

hello world-1hello world-2
# 在上面原有**的基礎上

"""1. 兩個裝飾器裝飾同乙個**遵循原則,離函式近的裝飾器先進行裝飾

2. 下面的裝飾器先裝飾完後將整個裝飾結果給第乙個裝飾器進行裝飾

3. 可以看做test3 = makeblod(makeitalic(test3)) 執行過程同上

"""@makebold

@makeitalic

def test3():

return "hello world-3"

列印結果

hello world-3
import time

def get_run_time(flag):

"""如果flag值為1 print輸出的結果為整數;其他則輸出浮點數型別

裝飾器工廠函式的功能

1. 接收額外引數-->內部**使用

2. 產生裝飾器物件

"""def get_time(*args, **kwargs):

# 打包引數 args = (99,) kwargs={}

func = args[0]

def inner(*args, **kwargs):

begin = time.time()

# 解包引數 (99) 暫存返回值 在最後返回

ret = func(*args, **kwargs)

end = time.time()

if flag == 1:

print("函式執行花費%d秒" % int(end-begin))

else:

print("函式執行花費%f秒" % (end-begin))

return ret

return inner

return get_time

# 1 呼叫裝飾器工廠函式 接收引數生成裝飾器 get_time = get_run_time(1)

# 2 @裝飾器 對下面的函式進行裝飾 func1 = get_time(func1)

@get_run_time(1)

def func1(number):

time.sleep(0.5)

print("in func1 這個人有%d歲" % number)

return 200

ret = func1(99)

print(ret)

列印結果

in func1 這個人有99歲

函式執行花費0秒

200

函式內帶有引數的情況可以使用不定長引數或者關鍵字引數進行傳參

class mc(object):

def __init__(self, func):

"""類似裝飾器函式的外層函式 接收被裝飾的函式引用 儲存"""

self.func = func

def __call__(self, *args, **kwargs):

"""使用__call__方法讓物件 像函式一樣()進行呼叫"""

print("被裝飾的函式開始執行")

ret = self.func(*args, **kwargs)

print("執行結束")

return ret

# 類裝飾器只能實現一部分裝飾器函式的功能 比如 裝飾器工廠

@mcdef f1(number, number2):

print("in f1")

# f1 = mc(f1) # 例項物件 = 類名()

f1(1,1) # 例項物件() ----> 例項物件.__call__()

python閉包以及裝飾器

通俗的定義 如果在乙個內部函式裡,對在外部作用域 但不是在全域性作用域 的變數進行引用,那麼內部函式就被認為是閉包 closure 它只不過是個 內層 的函式,由乙個名字 變數 來指代,而這個名字 變數 對於 外層 包含它的函式而言,是本地變數 1 示例一 2 usr bin python 3 en...

python閉包以及裝飾器

閉包 簡單理解 所謂閉包簡單點說就是定義乙個函式,這個函式裡面還有乙個函式,此時裡面的函式和外面函式中的變數之間就產生了閉包關係。理解 def test num 裡面還有乙個函式 def test inner num inner 這個函式和外面函式的變數num之間就產生了閉包 print num n...

python閉包以及裝飾器

所謂閉包簡單點說就是定義乙個函式,這個函式裡面還有乙個函式,此時裡面的函式和外面函式中的變數之間就產生了閉包關係。定義乙個函式 def test num 裡面還有乙個函式 def test inner num inner 這個函式和外面函式的變數num之間就產生了閉包 print num num i...