一、闭包1、定义闭包是指作用于其上的扩展函数,包括在函数定义体中引用但在定义体中未定义的非全局变量。函数是否匿名并不重要,关键是它可以访问定义在定义体之外的非全局变量。闭包是一个函数,它保留定义函数时存在的自由变量的绑定,因此当函数被调用时,即使定义范围不再可用,这些变量仍然可以使用。(只有嵌套在其他函数中的函数可能需要处理不在全局范围内的外部变量。)人的话:闭包就是根据不同的配置信息得到不同的结果(代码示例)。闭包是由函数及其关联的引用环境组成的实体。2.代码示例deffo_out(int_out):deffo_in(int_in):returnint_in+int_outreturnfo_ina=fo_out(1)b=fo_out(1000)printa(1)printb(1000)output:220003注意如果定义体之外的变量是可变类型(如:list),可以使用append来传值。defmake_averager():series=[]defaverager(new_value):series.append()total=sum(series)returntotal/len(series)returnaverager如果定义体外的变量是不可变类型(number,character)字符串、元组等),可以在定义体中声明nonlocal,使其成为自由变量。defmake_averager():count=0total=0defaverager(new_value):nonlocalcount,totalcount+=1total+=new_valuereturntotal/countreturnaveragerOK,我们把闭包放在一边,再看看装饰器呢?2.装饰器1.定义装饰器是一个可调用对象,它的参数是另一个函数(被装饰的函数)。装饰器可以处理装饰后的函数并返回它,或者用另一个函数或可调用函数替换它。典型行为:用接受相同参数的新函数替换装饰函数,并且(通常)返回装饰函数本应返回的值,同时执行一些额外的操作。2.代码示例@clockdeffactorial(n):return1ifn<2elsen*factorial(n-1)以上等同于:deffactorial(n):return1ifn<2elsen*factorial(n-1)factorial=clock(factorial)可见装饰器其实是闭包的简写!3.装饰器什么时候运行?registry=[]defregister(func):print('运行寄存器(%s)'%func)registry.append(func)returnfunc@registerdeff1():print('runningf1()')@registerdeff2():print('runningf2()')if__name__=='__main__':print(u'started')f1()runningresultis:runningregister(
