1、闭包的概念closure:内部函数中对enclosing作用域的变量进行引用,外部函数返回内部函数名 2、函数实质与属性函数是一个对象:在内存中有一个存储空间函数执行完成后内部变量回收:引用计数不为零函数属性:特殊属性函数返回值例子passline = 60def func(val):print(‘%x’ % id(val)) # 查看变量名地址if val >= passline:print(‘pass’)else:print(‘failed’)def in_func(): # (val,)添加后是元组类型不能变的print(val) # 引用变量后说明变量添加到内函数属性中,使用时直接在内函数中查找in_func()return in_func# func(88)a =func(88) # 将变量名指向in_funcprint(a.__name__) # 查看变量名a() #实际是调用了in_func(),相当于a和in_func指向同一个函数,a和in_func只是函数名print(a) #查看in_func()在func函数属性中的地址print(a.__closure__) # 查看in_func()中的属性是否存在val变量,闭包属性3、闭包的作用和优点
- 实现了函数封装
- 提高代码的复用
4、将代码的公共部分抽出,用闭包的形式代替抽出部分,将要使用的函数当作参数例子:两个代码重复的方法:def my_sum(*arg):if len(arg) == 0: # 被除数不能为0 return 0 for val in arg: # 数据只能是int型 if not isinstance(val,int): return 0return sum(arg)def my_average(*arg): if len(arg) == 0: return 0 for val in arg: if not isinstance(val,int): return 0return sum(arg)//len(arg) print(my_sum(1,2,3,’2′))print(my_average())重构后:def my_sum(*arg):return sum(arg)def my_average(*arg):return sum(arg)//len(arg)def dec(func):def in_dec(*arg): if len(arg) == 0: # 被除数不能为0 return 0 for val in arg: # 数据只能是int型 if not isinstance(val,int): return 0return func(*arg)return in_decmy_sum = dec(my_sum) # 1、先调用dec,2、再将my_sum函数名指向函数in_decmy_average = dec(my_average) # 当使用my_sum函数时,3、调用in_dec,4、再调用my_sumprint(my_sum(1,2,3,’2′))print(my_average()) 5、装饰器:
- 装饰器用来装饰函数
- 返回一个函数对象
- 被装饰函数标识符指向返回的函数对象
- 语法:@deco
装饰器实质是对闭包的使用def dec(func):print(‘1、call dec’)def in_dec(*arg):print(‘3、call in_dec’)if len(arg) == 0:return 0for val in arg:if not isinstance(val,int):return 0return func(*arg)print(‘2、return in_dec’)return in_decprint(‘装饰器代码执行顺序:’)@dec # 等于my_sum = dec(my_sum)这句话def my_sum(*arg): # 装饰过后my_sum名指向in_dec函数对象,此时in_dec会调用原来的my_sum,要使用my_sum(1,2)才能调用print(‘4、call my_sum’)return sum(arg)# print(sum(arg))def average(*arg):return sum(arg)//len(arg) print(‘调用被修饰的函数后才会执行闭包中的函数’)print(my_sum(1,2,3))输出结果:装饰器代码执行顺序:1、call dec2、return in_dec调用被修饰的函数后才会执行闭包中的函数3、call in_dec4、call my_sum