閉包函式和裝飾器

2022-07-02 18:30:14 字數 4563 閱讀 3085

目錄

二、閉包函式的應用

裝飾器閉包:閉是封閉(函式內部巢狀函式),包是包含,閉包是指該內部函式對外部作用域而非全域性作用域的變數的引用。

為函式傳參的方式一:使用引數的形式

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...