闭包函数及装饰器
一、闭包函数
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')