一些关于python 装饰器的个人理解


Posted in Python onAugust 31, 2020

装饰器

本质是一个接受参数为函数的函数。
作用:为一个已经实现的方法添加额外的通用功能,比如日志记录、运行计时等。

举例

1.不带参数的装饰器,不用@

# 不带参数的装饰器
def deco_test(func):
  def wrapper(*args, **kwargs):
    print("before function")
    f = func(*args, **kwargs)
    print("after function")
    return f
  return wrapper

def do_something(a,b,c):
  print(a)
  time.sleep(1)
  print(b)
  time.sleep(1)
  print(c)
  return a

if __name__ == '__main__':
  # 不用@
  f = deco_test(do_something)("1","2","3")

输出:

before function
1
2
3
after function

个人理解:

相当于在 do_something 函数外面套了两个输出: before function 和 after function 。

2.不带参数的装饰器,用 @

# 不带参数的装饰器
def deco_test(func):
  def wrapper(*args, **kwargs):
    print("before function")
    f = func(*args, **kwargs)
    print("after function")
    return f
  return wrapper

@deco_test
def do_something(a,b,c):
  print(a)
  time.sleep(1)
  print(b)
  time.sleep(1)
  print(c)
  return a

if __name__ == '__main__':
  # 使用@
  f = do_something("1","2","3")

输出:

before function
1
2
3
after function

个人理解:

相当于执行 do_something 函数的时候,因为有 @ 的原因,已经知道有一层装饰器 deco_test ,所以不需要再单独写 deco_test(do_something) 了。

3.带参数的装饰器

# 带参数的装饰器
def logging(level):
  def wrapper(func):
    def inner_wrapper(*args, **kwargs):
      print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
      f = func(*args, **kwargs)
      print("after function: [{level}]: enter function {func}()".format(level=level, func=func.__name__))
      return f
    return inner_wrapper
  return wrapper

@logging(level="debug")
def do_something(a,b,c):
  print(a)
  time.sleep(1)
  print(b)
  time.sleep(1)
  print(c)
  return a

if __name__ == '__main__':
  # 使用@
  f = do_something("1","2","3")

输出:

[debug]: enter function do_something()
1
2
3
after function: [debug]: enter function do_something()

个人理解:

装饰器带了一个参数 level = "debug" 。

最外层的函数 logging() 接受参数并将它们作用在内部的装饰器函数上面。内层的函数 wrapper() 接受一个函数作为参数,然后在函数上面放置一个装饰器。这里的关键点是装饰器是可以使用传递给 logging() 的参数的。

4.类装饰器

# 类装饰器
class deco_cls(object):
  def __init__(self, func):
    self._func = func

  def __call__(self, *args, **kwargs):
    print("class decorator before function")
    f = self._func(*args, **kwargs)
    print("class decorator after function")
    return f

@deco_cls
def do_something(a,b,c):
  print(a)
  time.sleep(1)
  print(b)
  time.sleep(1)
  print(c)
  return a

if __name__ == '__main__':
  # 使用@
  f = do_something("1","2","3")

输出:

class decorator before function
1
2
3
class decorator after function

个人理解:

使用一个装饰器去包装函数,返回一个可调用的实例。 因此定义了一个类装饰器。

5.两层装饰器

# 不带参数的装饰器
def deco_test(func):
  def wrapper(*args, **kwargs):
    print("before function")
    f = func(*args, **kwargs)
    print("after function")
    return f
  return wrapper

# 带参数的装饰器
def logging(level):
  def wrapper(func):
    def inner_wrapper(*args, **kwargs):
      print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
      f = func(*args, **kwargs)
      print("after function: [{level}]: enter function {func}()".format(level=level, func=func.__name__))
      return f
    return inner_wrapper
  return wrapper

@logging(level="debug")
@deco_test
def do_something(a,b,c):
  print(a)
  time.sleep(1)
  print(b)
  time.sleep(1)
  print(c)
  return a

if __name__ == '__main__':
  # 使用@
  f = do_something("1","2","3")

输出:

[debug]: enter function wrapper()
before function
1
2
3
after function
after function: [debug]: enter function wrapper()

个人理解:

在函数 do_something() 外面先套一层 deco_test() 装饰器,再在最外面套一层 logging() 装饰器。

以上就是python 装饰器的一些个人理解的详细内容,更多关于python 装饰器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
17个Python小技巧分享
Jan 23 Python
使用Python的web.py框架实现类似Django的ORM查询的教程
May 02 Python
python将unicode转为str的方法
Jun 21 Python
python消费kafka数据批量插入到es的方法
Dec 27 Python
Python3解释器知识点总结
Feb 19 Python
python使用requests模块实现爬取电影天堂最新电影信息
Apr 03 Python
python之mock模块基本使用方法详解
Jun 27 Python
如何使用Python实现斐波那契数列
Jul 02 Python
Python django框架输入汉字,数字,字符生成二维码实现详解
Sep 24 Python
基于Python的自媒体小助手---登录页面的实现代码
Jun 29 Python
python操作redis数据库的三种方法
Sep 10 Python
python通过opencv调用摄像头操作实例分析
Jun 07 Python
Python常用模块函数代码汇总解析
Aug 31 #Python
PyTorch 导数应用的使用教程
Aug 31 #Python
PyTorch安装与基本使用详解
Aug 31 #Python
pycharm 添加解释器的方法步骤
Aug 31 #Python
解决Windows下python和pip命令无法使用的问题
Aug 31 #Python
Python函数__new__及__init__作用及区别解析
Aug 31 #Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
Aug 31 #Python
You might like
实现分十页分向前十页向后十页的处理
2006/10/09 PHP
php中引用符号(&)的使用详解
2013/11/13 PHP
php图片的二进制转换实现方法
2014/12/15 PHP
php使用标签替换的方式生成静态页面
2015/05/21 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
Extjs4中Form的使用之本地hiddenfield
2013/11/26 Javascript
在百度知道团队中快速审批新成员的js脚本
2014/02/02 Javascript
Nodejs爬虫进阶教程之异步并发控制
2016/02/15 NodeJs
Bootstrap滚动监听(Scrollspy)插件详解
2016/04/26 Javascript
谈谈JavaScript数组常用方法总结
2017/01/24 Javascript
js阻止默认右键的下拉菜单方法
2018/01/02 Javascript
浅谈vue项目重构技术要点和总结
2018/01/23 Javascript
vue头部导航动态点击处理方法
2018/11/02 Javascript
js 数据类型判断的方法
2020/12/03 Javascript
[47:48]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第三局
2016/02/28 DOTA
python使用webbrowser浏览指定url的方法
2015/04/04 Python
Python简单获取自身外网IP的方法
2016/09/18 Python
Python竟能画这么漂亮的花,帅呆了(代码分享)
2017/11/15 Python
python实现媒体播放器功能
2018/02/11 Python
对tensorflow 的模型保存和调用实例讲解
2018/07/28 Python
python递归法解决棋盘分割问题
2019/07/17 Python
python实现输入的数据在地图上生成热力图效果
2019/12/06 Python
python开发前景如何
2020/06/11 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
2020/09/23 Python
CSS3中的Media Queries学习笔记
2016/05/23 HTML / CSS
CSS3 实现雷达扫描图的示例代码
2020/09/21 HTML / CSS
HTML5中Canvas与SVG的画图原理比较
2013/01/16 HTML / CSS
SportsDirect.com马来西亚:英国第一体育零售商
2018/11/21 全球购物
毕业生教师求职信
2013/10/20 职场文书
路政管理专业推荐信
2013/11/11 职场文书
快递员岗位职责
2014/09/12 职场文书
财务会计实训报告
2014/11/05 职场文书
2014五年级班主任工作总结
2014/12/05 职场文书
大队委员竞选稿
2015/11/20 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
java中用float时,数字后面加f,这样是为什么你知道吗
2021/09/04 Java/Android