**装饰器 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 可以增强函数的功能,虽然编写起来有点复杂,但是使用起来非常方便灵活。
- 跟老司机学Python
- 了解Python
- 1、python简介
- 2、Python发展史
- 3、Python特点
- 4、Python解释器
- 入坑Python
- 1、Python环境搭建
- 2、设置环境变量
- 3、开始使用Python
- 4、运行Python程序
- 掌握Python基础
- Python基础知识
- Python运算符
- 算术运算符
- 比较运算符
- 赋值运算符
- 逻辑运算符
- 位运算符
- 成员运算符
- 身份运算符
- 运算符优先级
- Python的变量与常量
- Python数据类型
- Number数值
- String字符串
- List列表
- Tuple元组
- Dictionary字典
- Set集合
- Python流程控制语句
- 条件判断
- 循环控制
- Python函数
- 1、函数是什么
- 2、函数的定义
- 3、函数的参数
- 4、函数的调用
- 5、嵌套函数
- 6、递归函数
- 7、匿名函数
- 8、函数式编程
- 9、高阶函数
- 1、map
- 2、reduce
- 3、filter
- 4、sorted
- 10、返回函数
- 11、偏函数
- Python文件IO操作
- 标准输入输出
- 读写文件
- with读写文件
- Python高级特性
- 1、列表生成式
- 2、迭代器
- 3、生成器
- 4、装饰器
- Python模块初探
- 1、模块与包
- 2、创建模块
- 3、模块中的作用域
- 4、模块的导入
- Python面向对象编程
- 类与对象
- 类的定义及使用
- 面向对象特性
- 类中的访问域
- 查看对象详情
- Python面向对象进阶
- 类中的方法
- 类中的特殊成员
- 限制对象的属性
- 再聊多继承
- 装x式创建类
- 创建元类
- Python内置模块
- os模块
- sys模块
- random模块
- time模块
- datetime模块
- shutil模块
- collections模块
- base64模块
- json模块
- hashlib模块
- xml模块
- 1. SAX解析XML
- 2. DOM解析XML
- 3. ElementTree解析XML
- urllib模块
- logging模块
- re模块
- Python第三方模块
- Pillow与PIL
- Requests
- Tablib
- Xpinyin
- Chardet
- Pycurl
- Virtualenv
- Python操作数据库
- Mysql操作
- Sqllite操作
- Mongodb操作
- Redis操作
- Python的GUI编程
- Python中GUI的选择
- Tkinter
- wxPython
- Socket网络编程
- Socket网络编程简聊
- Socket内建方法
- TCP协议编程
- UDP协议编程
- TCP与UDP
- Python电子邮件
- SMTP发邮件
- POP3收邮件
- IMAP收邮件
- 进程线程
- 进程与线程
- 进程编程
- 使用进程池
- 进程间的通信
- 线程编程
- 使用线程锁
- Python的GIL
- Web编程
- WSGI介绍
- Web框架
- Flask使用
- 模板jinjia2使用
- 项目结构规划
- 异步与协程
- 概念扫盲
- 异步IO进化之路
- 协程是什么
- yield协程编程
- yield from
- asyncio
- async与await
- aiohttp之client
- aiphttp之server
- 网络爬虫
- 网络爬虫简聊
- Beautiful Soup模块的使用
- pyquery 模块的使用
- selenium模块的使用
- 爬取段子实例
- 错误与调试
- 错误
- 错误处理
- 抛出错误
- 高效的调试
- Python重要语句
- pass语句
- return语句
- Python开发必知
- pip使用详解
- 如何对列表进行迭代
- 如何对字典进行迭代
- 字符串格式化
- 知识扩展
- 网络模型
- GUI是什么