闭包:
就是内层函数对外层函数(非全局变量的)非全局变量的引用
def func(): name = ‘老人家‘ def func1(): print(name)#局部变量对全局变量的引用 因为并没有在这个函数总定义name只是在它的父级定义了 return func1 func()()
闭包函数:
内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
#函数内部定义的函数称为内部函数
为什么使用闭包:
闭包的使用就是开辟一个不是立刻关闭的空间
因为我们的函数每当执行完就会关闭这个函数 ,但是如果我们的是个嵌套函数,我们执行完父级的过程了 但是子函数中的内容还没有执行,这个时候该怎么办呢? 这个时候就可以使用闭包让父级函数不能关闭
进而可以让我们马上使用子函数中的内容
def func():#定义一个父级函数 name=‘eva‘ def inner():#在这个父级函数中再定义一个子函数 #这个子函数从它的开始到它的结束就是整个闭包 print(name) #这个是引用父级函数内的变量name #使用闭包就是防止父级函数使用完之后不能使用子函数了 所以我们就定义一个闭包 然后让父级函数不能立刻关闭 进而调用子函数 # return inner #为了让我们能使用子函数就把子函数的名字给返还出去 f= func() f()
闭包的整个过程就是仔内存中开辟一个空间这个空间并不是父级函数执行完之后就会立刻关闭的,一般的都是函数执行是开辟一个空间然后执行完之后就关闭 闭包个并不是这个样 这个是在内存中,开辟一个不是立刻关闭的空然后当父级执行完 又可以让子函数在这个空间内执行,然后执行完等许久不用了 python的回收机制就会把这个内存给回收了
检测闭包:
我们也可以检测这个函数是不是属于闭包
判断闭包函数的方法__closure__
name = ‘alex‘ def func(): def Aveo(): print(name)#这时候这个name引用的不是父级的变量了是全局变量了 所以就不是闭包了 Aveo() print(Aveo.__closure__) #这个必须是这个写在子函数的结束位置 才能测试 func()
def fun(name):
#其实这里省略了一部name = ‘hhh‘ #送一子函数还是引用了父函数的内容 那么就是闭包
def func1():
print(name)
func1()
print(func1.__closure__) #在子函数的结束检测子函数是不是闭包
fun(‘hhh‘)
闭包函数的嵌套:
def wrapper(): money =100 def func(): name= ‘eva‘ def inner(): print(name,money) return inner return func f= wrapper()#这一步就是子函数f=func i =f() #i = inner i()
闭包的面试题:
name = ‘老南华‘ def wraaper(n): #这里相当于省略了一个n=name=‘老南华‘ def inner(): print(n) inner() print(inner.__closure__) wraaper(name)
函数的装饰器:
其实函数的名字也是特殊的变量 所以函数名是可以进行传递的
# 函数名是函数的名字,本质:变量,特殊的变量。
# 函数名() 执行此函数。
什么是装饰器:
在不改变原函数的执行的情况下,为原函数增加额外的功能
import time #因为是测试代码的运行时间的 所以一就需要导入时间模块 def func1(): print(‘你想干什么 还想测试我‘) # 我们来做一个测试一个函数的功能就是测试这个函数的效率的 def timmer(f): def inner():#在嵌套一个函数 start_time = time.time() #开始时间 f() time.sleep(0.3) #因为你做的是测试一个函数的运行效率但是代码在计算机中运行快的 几乎不可见,那么我们就需要加个让它延迟3秒的功能就是调用sleep然后延迟0.3秒 end_time=time.time() #结束时间 print(‘此函数的执行效率%s‘%(end_time-start_time)) return inner #把这个函数名返回给父级以便于调用 f = timmer(func1) f()
大家可以看到我们最后的赋值操作需要几步 那么如果我们再定义其他的修改的功能呢 ?就需要再定义新的功能再重新赋值吗?不 我们为了简化操作就定义了魔法糖
魔法糖的运用
import time def wraaper(f): def inner(): start_time = time.time() #开始时间 f() time.sleep(0.4) #为了防止此程序太快计算机看不到 我们就让它延迟0.3秒 end_time=time.time() print(‘此函数的执行效率%s‘ % (end_time - start_time)) return inner @ wraaper #大家看魔法糖的运用 就是在要测试的函数上定义一个@魔法符号 然后让它加上执行测试功能的函数的名称即可 def func(): print(‘就是你要测试我啊‘) func()
被装饰函数带参数的装饰器:
import time def timmer(f): # f = func1 函数名 def inner(*args,**kwargs): start_time = time.time() f(*args,**kwargs) time.sleep(0.3) end_time = time.time() print(‘此函数的执行效率%s‘ % (end_time - start_time)) return inner @timmer # func1 = timmer(func1) # inner def func1(a,b): print(a,b) print(‘你有病呀,领导,测试我的执行效率干甚。‘) func1(1,2) #进行传递参数
格式: