1.闭包(Closure)的概念:
内部函数中对enclosing作用域的变量进行引用
1 passline = 60 2 def func(val): 3 print('%x' % id(val)) 4 if val >= passline: 5 print('pass') 6 else: 7 print('faild') 8 9 def in_func(): 10 print(val) 11 12 in_func() 13 return in_func 14 15 f = func(80) 16 f() #in_func 17 print(f.__closure__)
运行结果:
5d4ff910 pass 80 80 (<cell at 0x000001B37C8B6CD8: int object at 0x000000005D4FF910>,)按照正常的理解,当执行完func函数后,in_func函数无法使用func函数作用域内的变量val,但是通过上面的代码,可以看到val添加到了in_func的__closure__属性中(in_func的属性__closure__对val变量进行了引用,func执行完成后val没有被释放掉),
也就是说,在函数闭包中,内部函数中对enclosing作用域的变量进行引用,并将引用变量添加到了内部函数__closure__属性中
2.装饰器
所谓装饰器,是用来装饰函数,并且返回一个函数对象
如以下求和与求平均值的两个方法:
def my_sum(*args): if len(args) == 0: return 0 for item in args: if not isinstance(item, int): return 0 return sum(args) def my_average(*args): if len(arg) == 0: return 0 for item in args: if not isinstance(item, int): return 0 return sum(args) / len(args) print(my_sum(1,2,3)) print(my_average(2,3,4,'1'))其中,两个方法中都有相同的一段的容错处理代码:
if len(arg) == 0: return 0 for item in arg: if not isinstance(item, int): return 0遵循程序设计的DRY原则,这段代码应该进行封装处理,这时便可引入函数闭包
def dec(func): def in_func(*args): if len(args) == 0: return 0 for item in args: if not isinstance(item, int): return 0 return func(*args) return in_func def my_sum(*args): return sum(args) def my_average(*args): return sum(args) / len(args) my_sum=dec(my_sum) my_average=dec(my_average) print(my_sum(1,2,3)) print(my_average(2,3,4,'1'))这样就对重复的代码进行了封装。而装饰器是一种语法糖,简化了代码的编写
def dec(func): print('dec called') def in_func(*args): if len(args) == 0: return 0 for item in args: if not isinstance(item, int): return 0 return func(*args) return in_func @dec def my_sum(*args): print('my_sum called') return sum(args) @dec def my_average(*args): print('my_average called') return sum(args) / len(args) # my_sum=dec(my_sum) # my_average=dec(my_average) print(my_sum(1,2,3)) print(my_average(2,3,4,'1'))运行结果:
dec called dec called my_sum called 6 0 程序执行到@dec时,调用 dec方法,返回in_dec,my_sum方法重新被赋值my_sum=in_dec(被装饰函数指向新的函数) 所以,装饰器@dec的作用就如同执行这行代码: my_sum=dec(my_sum)
转载于:https://www.cnblogs.com/liubiao/p/5278335.html