目錄
三、三層裝飾器
閉是封閉(函式內部的函式),包是包含(該內部函式對外部作用域而非全域性作用域的變數的引用)。
閉包就是指:函式內部的函式 對外部作用域 而非全域性作用域 的引用。
閉包函式的作用:可以把 閉包函式內部的變數 + 閉包函式內部的函式 這兩者包裹在一起, 然後通過返回值的形式返回出來。
閉包函式的特點:返回的函式物件,不僅僅是乙個函式物件,在該函式外還包裹了一層作用域,這使得,該函式無論在何處呼叫,優先使用自己外層包裹的作用域。
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中,函式也是當做物件,從而有裝飾器這一種特殊的用法。有引數的裝飾器就是在外面一層...