閉包函式與裝飾器

2022-09-16 21:18:18 字數 3960 閱讀 2373

目錄

三、三層裝飾器

閉是封閉(函式內部的函式),包是包含(該內部函式對外部作用域而非全域性作用域的變數的引用)。

閉包就是指:函式內部的函式 對外部作用域 而非全域性作用域 的引用。

閉包函式的作用:可以把 閉包函式內部的變數 + 閉包函式內部的函式 這兩者包裹在一起, 然後通過返回值的形式返回出來。

閉包函式的特點:返回的函式物件,不僅僅是乙個函式物件,在該函式外還包裹了一層作用域,這使得,該函式無論在何處呼叫,優先使用自己外層包裹的作用域。

def f1(url):

def f2():

print(url)

return f2

res = f1() # res = f2

res() # res() == f2()

裝飾器:就是一種用來 為 被裝飾函式物件 新增額外功能的函式

特點:不改變原函式的**

不改變原函式的呼叫方式

import time

def index():

print('hello world')

time.sleep(1)

def f2():

print('f2')

time.sleep(2)

start = time.time()

index()

end = time.time()

print(f'run time is ')

start = time.time()

f2()

end = time.time()

print(f'run time is ')

index 和 f2 的功能一樣,而且可以發現對他們的使用方式也是一樣的,因此可以想辦法將呼叫它們的**簡化,即可以再定義乙個函式來使用它們。

第一種方法:改變呼叫方式

import time

def index():

print('hello world')

time.sleep(1)

def time_count(func):

start = time.time()

func()

end = time.time()

print(f' run time is ')

time_count(index)

可以發現,這樣做和上面一種方法得到的結果是一樣的,但是可以發現使用index的方法不一樣了。

第二種方法:包給函式-外包

import time

def index():

print('hello world')

time.sleep(1)

def time_count(func):

start = time.time()

func()

end = time.time()

print(f' run time is ')

# f = time_count(index)

# f() # 這裡的f其實就是在呼叫index函式,但如果命名為f,使用者就不知道你在呼叫index

index = time_count(index)

index() # 新變數也命名為index,對使用者來說,就是在呼叫之前的index,只不過功能更新了

沒有改變index的源**,也沒有改變index函式的呼叫方式,這裡的time_count函式就是裝飾器。

我們做了如下調整:

import time

def index():

print('hello world')

time.sleep(1)

return 123

def time_count(func):

start = time.time()

res = func()

end = time.time()

print(f' run time is ')

return res

index = time_count(index)

res = index()

print(f'res:')

最後可以返回index函式的返回值 123。

import time

def home(name):

print(f'welcome to home page')

time.sleep(1)

return name

def time_count(func):

start = time.time()

res = func(*args,**kwargs)

end = time.time()

print(f' time is ')

return res

print(f'res:')

在被裝飾函式正上方,並且是單獨一行寫上@裝飾器名

import time

def time_count(func):

start = time.time()

res = func(*args,**kwargs)

end = time.time()

print(f' run time is ')

return res

@time_count

def home(name):

print(f'welcome to home page')

time.sleep(1)

return name

res = home('egon')

print(f'res:')

效果和上面乙個方法一樣

def deco(func):

res = func(*args,**kwargs)

return res

按模板寫就行了

套三層的裝飾器,其實是指含參裝飾器

username_list = 

def sanceng(role):

def login_deco(func):

if username_list:

print('請勿重複登入')

res = func(*args,**kwargs)

return res

username_lnp = input('請輸入使用者名稱:')

pwd_inp = input('請輸入密碼:')

with open(f'_info.txt','r',encoding='utf8') as fr:

for user_info in fr:

username,pwd = user_info.strip().split(':')

if username_lnp == username and pwd_inp== pwd:

print('登入成功')

res = func(*args,**kwargs)

return res

else:

print('登陸失敗')

return login_deco

@sanceng('user')

def index(x,y):

print('index')

print('x,y',x,y)

return 123

因為sanceng('user') 返回 login_deco,

所以上面的函式其實就是:

@login_deco

def index(x,y):

print('index')

print('x,y',x,y)

return 123

res = index(10,20)

閉包函式與裝飾器

一 閉包函式 定義在函式內部的函式,並且該函式包含對外部函式作用域中名字的引用,該函式就稱為閉包函式。乙個持有外部環境變數的函式就是閉包,閉包 函式塊 定義函式時的環境。閉包函式是乙個能記住巢狀作用域變數值的函式,儘管作用域已經不存在 工廠函式定義了乙個外部的函式,這個函式簡單的生成並返回乙個內嵌的...

閉包函式與裝飾器

八.閉包函式 定義在函式內部的函式,並且該函式包含對外部函式作用中名字的引用,該函式就稱為閉包函式 閉 指的是定義在函式內部的函式 作用域關係 在函式定義階段就規定死了,與呼叫位置無關 def outter x 2def inner x 1 print from inner x return inn...

裝飾器與閉包

閉包 內層函式呼叫外層函式的引數,並且返回內層函式,叫做閉包。裝飾器 是裝飾器的符號 裝飾器是對閉包的一種利用,內層函式呼叫外層函式的引數,並且返回內層函式,叫做閉包,把呼叫的引數,換成函式,就是裝飾器,因為python中,函式也是當做物件,從而有裝飾器這一種特殊的用法。有引數的裝飾器就是在外面一層...