闭包函数及装饰器
一、闭包函数
1.1 函数传参的方式一
def func(x):
print(x)
func(1)
func(1)
func(1)
-------------------------------------------------------------
1
1
1
1.2 函数传参的方式二
闭包函数,把变量和函数一起包起来,下次要用直接调用
#这样传就不会每一次传参的时候都输入
def outter(x):
x = 1
def inner():
print(x)
return inner
f = outter(1)
f()
f()
f()
---------------------------------------------------------
1
1
1
让我们再看一个利用闭包函数爬取网站的例子吧!
import requests
def func(url):
def get_res():
response = requests.get(url)
print({url})
return get_res
baidu = func('https://www.baidu.com')
baidu()
baidu()
-----------------------------------------------------------
{'https://www.baidu.com'}
{'https://www.baidu.com'}
二、装饰器
2.1 什么是装饰器
装饰器:装饰的工具(函数),这个函数有装饰的作用
装饰器本质就是一个函数A,装饰的对象也是一个函数B,用一个函数A去装饰一个函数B
2.2 装饰器遵循的原则
-
不改变函数B的调用方式
-
不改变函数B的源代码
def A():
"""装饰器"""
pass
def B():
"""被装饰的对象"""
pass
B()
2.3 装饰器举例
打印函数运行的时间
# 2.3.1 改变了函数体代码,没改变调用方式(不是装饰器,没有遵循装饰器原则)
import time
def index():
start = time.time()
print('您好')
time.sleep(1)
end = time.time()
print(end-start)
index()
----------------------------------------------------------
您好
1.0013189315795898
# 2.3.2 没改变调用方式,也没改变源码,但是不通用(不是装饰器,没有遵循装饰器原则)
import time
def index():
'''被装饰的函数'''
print('hello')
def index1():
print('hello1')
start = time.time()
index()
time.sleep(1)
end = time.time()
print(end-start)
start = time.time()
index1()
time.sleep(1)
end = time.time()
print(end-start)
-----------------------------------------------------------
hello
1.0003104209899902
hello1
1.000321388244629
#每次调用的时候都得运行一遍,真的很麻烦
# 2.3.3 真正的装饰器
import time
def index():
print('您好啊!')
time.sleep(1)
def deco(func): # func = 真正的index
'''装饰器'''
def f1(): #重新创建的index
start = time.time()
func() #真正的index
end = time.time()
print(end-start)
return f1
index = deco(index)
index() #f1
2.4 三层装饰器
#利用装饰器写一个装饰器
def auth(engine):
def login(func):
def inner(*args,**kwargs):
#登录功能
if engine =='file':
username = input('username:')
pwd = input('pwd:')
if username =='jiayi'and pwd =='123':
print('登录成功')
res = func(*args,**kwargs) #shopping()
print('登录失败')
elif engine =='db':
print('账号来自于数据库,非法请求')
return inner
return login
@auth('db')
def shopping():
print('shopping')
shopping()
-------------------------------------------------------------------------
账号来自于数据库,非法请求
2.5 装饰器模板
2.5.1 双层装饰器
def outter(func):
def wrapper(*args.**kwargs): #wrapper是未来要运行的函数
#加功能
res = func(*args,**kwargs) #func是被装饰的函数
return res
return wrapper
@outter
def shopping():
print('shopping')
2.5.2 三层装饰器
# 三层装饰器:给双层装饰器加参数
def sanceng (engine):
def outter(func):
def wrapper(*args,**kwargs): # wrapper是未来要运行的函数
#加功能
print(engine)
res = func(*args,**kwargs) #func是被装饰的函数
return res
return wrapper
return outter
@sanceng('db')
def shopping():
print('shopping')