? 闭:封闭
? 包:包裹
? 闭包函数必须在函数内部定义
? 闭包函数可以引用外层函数的名字
? 闭包函数就是函数嵌套,函数对象,名称空间与作用域的结合体
直接传参
def fun(x): print(x)func(1000)
def fun(x):
print(x)
func(1000)
通过闭包函数传参
def outer(num): def inner(): print(num) return innerfunc = outer(100)#inner地址func()
def outer(num):
def inner():
print(num)
return inner
func = outer(100)#inner地址
func()
什么是装饰器
装饰:装饰,修饰
器:工具
装饰器必须要遵循的‘开放封闭原则’
开放:对函数功能的添加是开放的
封闭:对函数功能的修改是封闭的
装饰器的作用
在不修改被装饰对象源代码与调用方式的前提下,添加新的功能
被修饰对象:需要添加功能的函数
装饰对象:添加功能函数
应用
统计时间
登录认证
可以解决冗余代码,提高代码可扩展性
小实例结合time包
import time# 被修饰函数def download_movie():#download_movie函数名 print('开始下载电影') time.sleep(3)#模拟下载时间 print('电影下载成功')start_time = time.time()download_movie()end_time = time.time()print(f'电影下载时间:{end_time - start_time}')>>>开始下载电影电影下载成功电影下载时间:3.0007519721984863#装饰器即装饰函数def time_record(func):#time_record装饰器的函数名,func形参,用来接收实参 def inner():#内部函数名 start_time = time.time() func()#执行接收到的函数 end_time = time.time() print(f'电影下载时间:{end_time - start_time}') return inner#调用time_record这个函数返回inner的内存地址#print(time_record(download_movie))#time_record(download_movie)是一个内存地址download_movie = time_record(download_movie)download_movie()>>>开始下载电影电影下载成功电影下载时间:3.000049352645874开始下载电影电影下载成功电影下载时间:3.00085186958313#1、被修饰对象有返回值import timedef download_movie(): print('开始下载电影') time.sleep(3)#模拟下载时间 print('电影下载成功') return '小泽.mp4'#调用函数返回'小泽.mp4'def time_record(func):#func<---download_movie def inner(): start_time = time.time() res = func()#res = '小泽.mp4' # print(res)#res字符串 end_time = time.time() print(f'电影下载时间:{end_time - start_time}') return res#调用函数inner返回res # print(inner()) return inner#调用函数time_record返回inner,此时才是地址# print(time_record(download_movie))#inner地址download_movie = time_record(download_movie)download_movie()>>>开始下载电影电影下载成功电影下载时间:3.0000083446502686#2、被修饰对象有参数import timedef download_movie(url):#url用来接收参数 print('开始下载电影') time.sleep(3)#模拟下载时间 print('电影下载成功') return '小泽.mp4'#返回'小泽.mp4'def time_record(func):#func用来接收被修饰函数func<---download_movie def inner(url):#url接收参数 start_time = time.time() res = func(url)#func(url)<----download_movie(url) end_time = time.time() print(f'电影下载时间:{end_time - start_time}') return res#把res即(download_movie(url))---->inner return inner#(download_movie(url))---->time_recorddownload_movie = time_record(download_movie)download_movie('https://www.jd.com/')>>>开始下载电影电影下载成功电影下载时间:3.0002450942993164#3、有多个参数import timedef download_movie(*args, **kwargs): print('开始下载电影') time.sleep(3)#模拟下载时间 print('电影下载成功') return '小泽.mp4'#把'小泽.mp4'def time_rcod(func): def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print(f'电影下载时间:{end_time - start_time}') return res return innerdownload_movie = time_rcod(download_movie)download_movie('https://www.baidu.com/')>>>开始下载电影电影下载成功电影下载时间:3.000089168548584
import time
# 被修饰函数
def download_movie():#download_movie函数名
print('开始下载电影')
time.sleep(3)#模拟下载时间
print('电影下载成功')
start_time = time.time()
download_movie()
end_time = time.time()
print(f'电影下载时间:{end_time - start_time}')
>>>开始下载电影
电影下载成功
电影下载时间:3.0007519721984863
#装饰器即装饰函数
def time_record(func):#time_record装饰器的函数名,func形参,用来接收实参
def inner():#内部函数名
func()#执行接收到的函数
return inner#调用time_record这个函数返回inner的内存地址
#print(time_record(download_movie))#time_record(download_movie)是一个内存地址
download_movie = time_record(download_movie)
电影下载时间:3.000049352645874
开始下载电影
电影下载时间:3.00085186958313
#1、被修饰对象有返回值
def download_movie():
return '小泽.mp4'#调用函数返回'小泽.mp4'
def time_record(func):#func<---download_movie
res = func()#res = '小泽.mp4'
# print(res)#res字符串
return res#调用函数inner返回res
# print(inner())
return inner#调用函数time_record返回inner,此时才是地址
# print(time_record(download_movie))#inner地址
电影下载时间:3.0000083446502686
#2、被修饰对象有参数
def download_movie(url):#url用来接收参数
return '小泽.mp4'#返回'小泽.mp4'
def time_record(func):#func用来接收被修饰函数func<---download_movie
def inner(url):#url接收参数
res = func(url)#func(url)<----download_movie(url)
return res#把res即(download_movie(url))---->inner
return inner#(download_movie(url))---->time_record
download_movie('https://www.jd.com/')
电影下载时间:3.0002450942993164
#3、有多个参数
def download_movie(*args, **kwargs):
return '小泽.mp4'#把'小泽.mp4'
def time_rcod(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return res
download_movie = time_rcod(download_movie)
download_movie('https://www.baidu.com/')
电影下载时间:3.000089168548584
装饰器模板
def wrapper(func): def inner(*args,**kwargs): #添加功能 res = func(*args,**kwargs) #添加功能 return res return innerdef func1(): passfunc1 = wrapper(func1)#func1被修饰函数,wrapper修饰函数func1()
def wrapper(func):
def inner(*args,**kwargs):
#添加功能
res = func(*args,**kwargs)
def func1():
pass
func1 = wrapper(func1)#func1被修饰函数,wrapper修饰函数
func1()
装饰器语法糖
装饰器的语法糖是属于装饰器的
@:装饰器的语法糖
注意:在使用装饰器的语法糖时,装饰器必须定义在被装饰函数前
# 统计函数执行时间装饰器def wrapper(func): # 被装饰对象 def inner(*args, **kwargs): # 被装饰对象的参数 # 调用前增加新功能 start_time = time.time() # 调用被装饰对象,并接收返回值 res = func(*args, **kwargs) # 调用后添加新功能 end_time = time.time() print(end_time - start_time) return res return inner# func函数需要执行3秒# 无参装饰器# 使用装饰器@wrapper # wrapper(func) ---> funcdef func(): time.sleep(3)
# 统计函数执行时间装饰器
def wrapper(func): # 被装饰对象
def inner(*args, **kwargs): # 被装饰对象的参数
# 调用前增加新功能
# 调用被装饰对象,并接收返回值
# 调用后添加新功能
print(end_time - start_time)
# func函数需要执行3秒
# 无参装饰器
# 使用装饰器
@wrapper # wrapper(func) ---> func
def func():
time.sleep(3)
原文链接:http://www.cnblogs.com/yafeng666/p/11843169.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728