python基础17-闭包函数-无参装饰器
今日学习
闭包函数简介
闭包函数的实际应用
装饰器简介
装饰器推导流程(重要)
装饰器功能完善
装饰器统一使用模板(通用)
装饰器语法糖
装饰器修复计数(待补充)
闭包函数概念
1.定义在函数内部的函数
2.内部函数使用了外部函数名称空间的名字
ps:只有符合上述两个特征的函数才能称为闭包函数
---------------------------
def warapper(username): #定义warapper函数 username是形参
#username = 'jason'
def index():
print(username)
return index
res()
闭包函数的实际应用
import requests
#方式一:
def get(url):
return requests.get(url).text
#方式二:
def page(url): 1. #url为形参,page(https:xx实参)相
def get(): 2. #还未调用不看。
return requests.get(url).text 3. #get获取(url)形参位
return get 4.#返回get
# 方式一下载同一页面
get('https://www.python.org')
get('https://www.python.org')
get('https://www.python.org')
……
# 方式二下载同一页面
python=page('https://www.python.org') #将page('https://www.python.org')传给python
python()
python()
python()
……
装饰器
可以理解为:闭包+函数对象+嵌套
在不改变被装饰对象原来的调用方式和内部代码的情况下,给被装饰对象添加新的功能
-
装饰器推导
-------------------------问题运行代码块并打印出代码块运行时间-------------------------- # 改变了代码冗余问题(函数传参) import time # # 需求,打印 # #函数传参 案例一 # def index(x, y): # # start = time.time() # time.sleep(3) # print('index %s %s' % (x, y)) # stop = time.time() # print(stop - start) # index(111,222) #但是需求一次,我们就要做一次print打印,代码冗余繁琐。将print和time优化成函数体 ------------------------------------------------------------ # #函数传参 方案二 def index(x,y): time.sleep(3) print('index %s %s' % (x, y)) def wrapper(): start = time.time() index(1111, 2222,111) #太死板,如果有改变的话,代码会冗余,位置实参不填写正确也会报错。 stop = time.time() print(stop - start) wrapper() #此时我们将index(1111, 2222,111)打印需求修改,还有改代码。 ---------------------------------------------------------------------------- 方案3:方案三优化一 将index(x,y)传参,设置wrapper # 函数传参 def index(x,y): time.sleep(3) print('index %s %s %s' % (x, y)) def wrapper(g,z): start = time.time() index(g,z) stop = time.time() print(stop - start) # 打印 wrapper(111,2223) ----------------------------------------------------------------------------------- # 方案3优化二 优化wrapper函数,将index方案写活了 def index(x,y,z): time.sleep(2) print('index %s %s %s' % (x, y, z)) def wrapper(*args,**kwargs): start = time.time() index(*args,**kwargs) #warapper 灵活了,但是index比较死板,如果是再新增home功能, stop = time.time() # 还要再多写一遍函数体,所以尽可能的把index给做成变量。 print(stop - start) wrapper(111,2223,33333) ----------------------------------------------------------------------------------- # 方案3优化三#除了将设置warapper函数体后,将函数体内的index优化为传参。 def index(x, y, z): time.sleep(2) print('index %s %s %s' % (x, y, z)) print(index) def outer(func): def wrapper(*args, **kwargs): start = time.time() func(*args, **kwargs) # func实参成为了index,(*args,**kwargs)变为(x,y,z) stop = time.time() print(stop - start) return wrapper index = outer(index) #新定义index变量 index(11,22,33) # func(11,22,33) # 1.将index函数 赋值传给上面函数体中的func形参中,此时outer函数形参传给内层函数体(wrapper)下的func
-
推导总结
1.统计某个函数的运行时间 2.将统计函数运行时间的代码封装成了函数 3.直接封装成函数会改变调用方式 4.利用闭包函数传参尝试 5.利用重名替换原来函数名的功能 6.函数的参数 7.函数的返回值装饰器各种版本
-
装饰器各个版本
import time def home(): time.sleep(2) print('from home') return '执行home函数之后的返回值' """针对有参无参函数如何兼容""" def outer(xxx): def get_time(*args, **kwargs): start_time = time.time() res = xxx(*args, **kwargs) end_time = time.time() print('函数的执行时间是:', end_time - start_time) return res return get_time # @outer#装饰语法糖 #home = outer(home) home = outer(home) #outer(home)将home传参给outer(xxx) xxx = home() print(xxx) ------------------执行结果-------------------------------- from home 函数的执行时间是: 2.008957624435425 执行home函数之后的返回值 ----------------装饰器叙述总结---------------------- 1.首先定义了home代码功能块,然后outer为无参装饰器(可以理解为嵌套函数outer(xxx)函数体); 2.因为xxx为形参位,outer(home) 就是home作为实参传入xxx形参中。 3. 闭包函数内层中res = xxx(*args, **kwargs) 相当于 res = home() 4.res变量 返回结果给get_time 5.get_time函数返回结果 6.定义一个新的home变量 home = outer(home) 7.home()调用
拓展小知识-return
-
def add(x, y): z = x + y return z # print(add(x, y)) #不加return 返回none print(add(1,2)) -----结果------ 3 -------------------- return返回值只能通过print打印才会显示出来,但在交互式模式下不需要print打印------- return的作用之一是返回计算的值
-
固定模板
---------------- 使用方法 模板 +@outer+代码块------------------- from functools import wraps #装饰器的修复技术 def outer(func_name): @wraps(func_name) # 仅仅是为了让装饰器不容易被别人发现 做到真正的以假乱真 def inner(*args, **kwargs): print('执行被装饰对象之前可以做的额外操作') res = func_name(*args, **kwargs) print('执行被装饰对象之后可以做的额外操作') return res return inner
-
装饰器语法糖
# 装饰器语法糖 import time @outer # home = outer(真正的函数名home) def home(): '''我是home函数 我要热死了!!!''' time.sleep(1) print('from home') return 'home返回值' # help(home) # print(home) home() # def index(): # '我是index函数 我的功能很强大' # pass # # help(index)