闭包:

首先说下闭包是什么?

闭包就是在函数内部定义的函数,包含对外部作用域的引用,但不包含全局作用域。因为函数的作用域在定义的时候就固定死了,所以闭包函数有自带作用域和延迟计算的特点。

闭包函数定义:如果一个内部函数,包含了对外部作用域的引用,但是不是包含全局作用域。那么这个函数就被认为是闭包函数。闭包函数可以使用“.__closure__” 来查看闭包函数的属性。下面我们来看一个示例:

deft():
money= 100
defs():print(money)return s #返回函数s,不是函数执行过的值
c=t()
c()print(c.__closure__) #查看属性

执行结果:

D:\Python\Python36-32\python.exe E:/Python/DAY-7/day7_笔记.py100(,)
Process finished with exit code 0
View Code

函数s就是在函数t中定义的内部函数

函数s引用了一个外部的变量money,但是不是全局变量。则函数s就是一个闭包函数。

装饰器:

装饰器本质可以是任意可调用对象,被装饰的对象也可以是任意可调用对象。

装饰器功能:

在不修改被装饰对象源代码以及调用方式的前提下,为其添加新的功能。

装饰器的语法:

在被装饰对象的正上方的单独一行,@装饰器名字。会把正下方的函数名调用装饰器,处理完返回给函数名。

多个装饰器:谁在上面谁先执行,谁在下面谁先计算。

示例:

import time #导入模块
importrandomdef timmer(func): #装饰器模块
def wrapper(): #定义一个闭包函数wrapper
stime = time.time() #闭包函数内 计算index的睡眠时间 ,这里是开始计算
func()      #执行index的函数内容
stptime = time.time() #index的函数执行完毕后的停止时间
print('run time is %s'%(stptime-stime)) #打印运行了多久
returnwrapper()def index(): #定义函数index
time.sleep(random.randrange(1,2)) #函数内执行睡一定时间,然后打印 欢迎信息
print('welecome to index page')
index= timmer(index) #调用装饰器

运行结果:

D:\Python\Python36-32\python.exe E:/Python/DAY-7/tmp.py
welecome to index page
run timeis 1.0000858306884766Process finished with exit code 0
View Code

上面这个是最简单的装饰器示例。如果我们还要传参,让用户感觉不出装饰器的怎么办?我们来看下面的。

示例:

importtimeimportrandom#装饰器
deftimmer(func):def wrapper(*args,**kwargs): #接受可变长参数
start_time =time.time()
res=func(*args,**kwargs) #接收保存对应函数 的return 返回值
stop_time=time.time()print('run time is %s' %(stop_time-start_time))return res #执行完毕 return 函数的返回值
returnwrapper#被装饰函数
@timmer#使用@方式调用装饰器
defindex():
time.sleep(random.randrange(1,5))print('welecome to index page')
@timmerdef home(name): #需求一个传入参数
time.sleep(random.randrange(1,3))print('welecome to %s HOME page' %name)return 123123123123123123123123123123123123123123 #return 有返回值
index()#调用 无参数传入
print(home('abc')) #调用传入参数‘abc’
执行结果:
D:\Python\Python36-32\python.exe E:/Python/DAY-7/tmp.py
welecome to index page
run timeis 2.0000545978546143welecome to abc HOME page
run timeis 2.0000154972076416
123123123123123123123123123123123123123123Process finished with exit code 0
View Code