闭包定义:在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包.
下面实现一个在执行方法的前后打印日志的场景
第一种方法装饰器
1.定义外层函数(要求参数只有一个,类型是函数类型,调用时传参传递的是原函数)
2.定义内层函数,在内层函数中,书写新的功能,并在合适的时机调用原函数
3.返回内部函数的地址
def t1_logger(fn):print("t1_logger_start")def logger1(*args, **kwargs):print(u'开始执行%s'% fn)res=fn(*args, **kwargs)print(u'结束执行%s'% fn)return resprint("t1_logger_end")return logger1
#在main方法执行之前,初始化t1_logger并执行,返回logger1方法,调用的时候再执行add1方法
@t1_logger
def add1(a,b):print("add1")return a+bif __name__ == '__main__':print(add1(1,2))print("end")#打印顺序 为
# t1_logger_start
# t1_logger_end
# 开始执行<function add1 at 0x000001EDE13AE790>
# add1
# 结束执行<function add1 at 0x000001EDE13AE790>
# 3
# end
第二种可以传递变量的装饰器
def t2_logger(name=None):print("t2_logger_start")def logger2(fn):print(u'开始执行%s'% name)print(u'结束执行%s'% name)return fnprint("t2_logger_start")return logger2#在main方法执行之前,初始化t2_logger并执行,初始化logger2,并执行logger2,返回fn。
@t2_logger(name="加法")
def add2(a,b):print("add2")return a+bif __name__ == '__main__':print(add2(1,2))print("end")
#打印顺序为
# t2_logger_start
# t2_logger_start
# 开始执行加法
# 结束执行加法
# add2
# 3
# end
第三种可以传递变量的装饰器,是在第一种的外层再装一层
def t3_logger(name=None):print("t3_logger_start")def decorate(fn):print("decorate_start")def logger3(*args, **kwargs):print(u'3开始执行%s'% name)res=fn(*args, **kwargs)print(u'3结束执行%s'% name)return resprint("decorate_end")return logger3print("t3_logger_end")return decorate@t3_logger(name="乘法")
def add3(a,b):print("add3")return a+bif __name__ == '__main__':print(add3(1,2))print("end")
# 打印的顺序为
# t3_logger_start
# t3_logger_end
# decorate_start
# decorate_end
# 3开始执行乘法
# add3
# 3结束执行乘法
# 3
# end