目錄
二、閉包函式的應用
裝飾器閉包:閉是封閉(函式內部巢狀函式),包是包含,閉包是指該內部函式對外部作用域而非全域性作用域的變數的引用。
為函式傳參的方式一:使用引數的形式
def func(x):
print(x)
func(1)
為函式傳參的方式二:包給函式def outter(x):
x = 2
def inner():
print(x)
return inner
f = outter(1)
f()
意義:返回的函式物件,不僅僅是乙個函式物件,在該函式外還包裹了一層作用域,這使得該函式無論在何處呼叫,優先使用自己外層包裹的作用域。
應用領域:延遲計算(原來是傳參,現在是包起來)、爬蟲領域。
def f1(url):#f1閉包函式
def spider():
print(url)
return spider#函式物件
taobao = spider('')
taobao()
所謂裝飾器就是用乙個函式給另乙個函式加功能而且不動原函式的**,不改變原函式的呼叫方式。
import time
def index():
"""被裝飾的函式"""
print('index')
time.sleep(1)
#為index增加計時功能
def time_coount(func):
"""裝飾器"""
def f1():
start = time.time()
func()
end = time.time()
print(end-start)
return f1
index = time_coount(index)#這裡第二個index是原來的index,但是第乙個index已經不是原來的index,而是進過裝飾之後的index
index()
裝飾器本身是函式,只不過用它來裝飾被裝飾的函式
裝飾器裝飾函式,不改變被裝飾函式源**
裝飾器裝飾函式,不改變被裝飾函式的呼叫方式
帶返回值
import time
def index():
"""被裝飾的函式"""
print('index')
time.sleep(1)
return 10
#為index增加計時功能
def time_coount(func):
"""裝飾器"""
def f1():
start = time.time()
res = func()#如果原函式有返回值只需要將其賦給乙個變數,然後將其在最內層返回
end = time.time()
print(end-start)
return res
return f1
index = time_coount(index)
print(index())
index
1.0000016689300537
10加引數
import time
def index(x,y,z = 10):
"""被裝飾的函式"""
print('index')
print(x,y,z)
time.sleep(1)
return 10
#為index增加計時功能
def time_coount(func):
"""裝飾器"""
start = time.time()
res = func(*args,**kwargs)
end = time.time()
print(end-start)
return res
index = time_coount(index)
index(10,20,30)
index
10 20 30
1.0003015995025635
為原函式加登入功能
import time
#為index增加計時功能
username_list =
def time_coount(func):
if username_list:
print('已經登入,請勿重複登入')
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print(end - start)
return res
else:
username_inp = input('請輸入使用者名稱:')
pwd_inp = input('請輸入密碼:')
with open('user_info.txt','r',encoding='utf-8') as fr:
for user_info in fr:
username,pwd = user_info.strip().split(':')
if username_inp == username and pwd_inp == pwd:
print('登陸成功')
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print(end - start)
return res
else:
print('登陸失敗')
@time_count
def index(x,y,z = 10):
"""被裝飾的函式"""
print('index')
print(x,y,z)
time.sleep(1)
return 10
#index = time_coount(index)
index(10,20,30)
功能:給雙層裝飾器加引數
在原來的要求上增加功能,需要判斷使用者動態的獲取使用者密碼的方式,如果是file
型別的,我們則讓使用者進行認證。
import time
#為index增加計時功能
username_list =
def auth(engine):
def time_count(func):
if engine == 'file':
if username_list:
print('已經登入,請勿重複登入')
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print(end - start)
return res
else:
username_inp = input('請輸入使用者名稱:')
pwd_inp = input('請輸入密碼:')
with open('user_info.txt','r',encoding='utf-8') as fr:
for user_info in fr:
username,pwd = user_info.strip().split(':')
if username_inp == username and pwd_inp == pwd:
print('登陸成功')
start = time.time()
res = func(*args, **kwargs)
end = time.time()
print(end - start)
return res
else:
print('登陸失敗')
else:
print('非法登入')
return time_count
@auth('file')
def index(x,y,z = 10):
"""被裝飾的函式"""
print('index')
print(x,y,z)
time.sleep(1)
return 10
#time_count = auth('file')
#index = time_count(index)
index(10,20,30)
請輸入使用者名稱:xiaozhu
請輸入密碼:12306
登陸成功
index
10 20 30
1.000612497329712
裝飾器語法糖
在被裝飾函式正上方,並且單獨一行@裝飾器名
裝飾器的模板
def deco(func):
"""加功能區域"""
res = func(*args,**kwargs)
return res
函式裝飾器和閉包
裝飾器是可呼叫的物件,其引數是另乙個函式 被裝飾的函式 裝飾器可能會處理被裝飾的函式,然後把它返回,或者將其替換成另乙個函式或可呼叫物件。裝飾器通常把函式替換成另乙個函式 defdeco func definner print running inner return inner deco def ...
閉包函式和裝飾器
目錄裝飾器 閉包即函式內部函式對外部作用域而非全域性作用域的引用,說白了就是將函式內部的變數拿到全域性來使用,還不會修改區域性變數的值 def outter x 5 def inner return x return inner f outter x f 1 print f print x 5 6使...
閉包函式和裝飾器
閉包函式 作用域關係在函式定義階段時就已經固定死了,與呼叫位置無關 即 在任意位置呼叫函式都需要跑到定義函式時尋找作用域關係 def f1 x 1 def inner print x x最後還是等於1,因為只看定義階段,return inner func f1 def f2 x 111111 fun...