**装饰器 decorator** 装饰器其本质就是一个函数,同样使用 def 定义。 那它与与他函数有什么区别呢? 普通函数是实现某种特定功能,装饰器是为被装饰的函数添加附加功能,而不需去修改原函数(锦上添花)。 装饰器特点: 1. 不修改被装饰的原函数 2. 不修改被装饰的原函数的调用方式 来个小示例: 假如你开发了一套后台管理系统,有下面几个功能: ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- def addUser(): print('添加用户成功') def delUser(): print('删除用户成功') ~~~ 程序运行了一段时间,领导想知道调用每种方法的时间日志,你就开始编写代码 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- import time def log(funName): time_str = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) print("[%s] 执行了 %s 方法" % (time_str, funName)) def addUser(): log(addUser.__name__) print('添加用户成功') def delUser(): log( delUser.__name__) print('删除用户成功') ~~~ 你信心满满的把代码提交到代码托管平台上,过了会,项目经理把你叫到办公室对你说:虽然你实现了功能,但是更改了生产环境中的代码,这就违反了软件开发中“开放-封闭”原则,即:已经实现的功能代码不允许被修改,但可以被扩展 * 封闭:已实现的功能代码块不应该被修改 * 开放:对现有功能的扩展开放 于是 ,你就想到了《跟老司机学Python》这章说的装饰器这种东西,完全符合 “开放-封闭”原则,继续修改代码 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- import time def log(func): def warpper(*args, **kwargs): time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) print("[%s] 执行了 %s 方法" %(time_str,func.__name__)) func(*args, **kwargs) return warpper @log #第一个 def addUser(): print('添加用户成功') @log #第二个 def delUser(): print('删除用户成功') ~~~ 在函数的章节我们已经知道 : 函数即变量 对上面代码中的两个 @log 进行说明 ~~~ 第一个 @log 相当于 log(addUser) 第二个 @log 相当于 log(delUser) ~~~ 从上面的程序可以看出:**装饰器** 就是 **高阶函数** 与 **嵌套函数** 的应用 这次提交代码后,经理感觉你做的不错,又提出了让你添加是谁操作了每种方法的日志,你又接着修改代码 ~~~ #!/usr/bin/env python3 # -*- coding:utf-8 -*- import time name = 'air'#假设这是你存储在 session 中的名字 def loger(who): def log(func): def warpper(*args,**kwargs): time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) print("%s 在 [%s] 执行了 %s 方法" %(who,time_str,func.__name__)) func(*args, **kwargs) return warpper return log @loger(name) def addUser(): print('添加用户成功') @loger(name) def delUser(): print('删除用户成功') addUser() delUser() ~~~ 最终调用结果 ~~~ air 在 [2017-10-06 17:14:17] 执行了 addUser 方法 添加用户成功 air 在 [2017-10-06 17:14:17] 执行了 delUser 方法 删除用户成功 ~~~ 小伙子干的不错,就等着升职加薪走上人生巅峰吧! 总结: decorator 可以增强函数的功能,虽然编写起来有点复杂,但是使用起来非常方便灵活。