一些关于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 相关文章推荐
python实现class对象转换成json/字典的方法
Mar 11 Python
Python对象类型及其运算方法(详解)
Jul 05 Python
利用python获取Ping结果示例代码
Jul 06 Python
python简易远程控制单线程版
Jun 20 Python
Python基于分析Ajax请求实现抓取今日头条街拍图集功能示例
Jul 19 Python
Pyqt5如何让QMessageBox按钮显示中文示例代码
Apr 11 Python
Python中的类与类型示例详解
Jul 10 Python
如何安装2019Pycharm最新版本(详细教程)
Sep 26 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
Keras之自定义损失(loss)函数用法说明
Jun 10 Python
Python如何合并多个字典或映射
Jul 24 Python
Python 使用dict实现switch的操作
Apr 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
239军机修复记
2021/03/02 无线电
espresso double下 咖啡粉超细时 饼压力对咖啡的影响
2021/03/03 冲泡冲煮
php设置编码格式的方法
2013/03/05 PHP
phpcms手机内容页面添加上一篇和下一篇
2015/06/05 PHP
Symfony2在Nginx下的配置方法图文教程
2016/02/04 PHP
javascript parseInt 大改造
2009/09/27 Javascript
基于JQuery的多标签实现代码
2012/09/19 Javascript
一个JavaScript去除字符串末尾的空白实例代码
2014/09/22 Javascript
完美兼容各大浏览器的jQuery仿新浪图文淡入淡出间歇滚动特效
2014/11/12 Javascript
js实现九宫格图片半透明渐显特效的方法
2015/02/16 Javascript
全面解析Bootstrap排版使用方法(标题)
2015/11/30 Javascript
基于jQuery实现美观且实用的倒计时实例代码
2015/12/30 Javascript
基于JavaScript实现点击页面任何位置返回
2016/08/31 Javascript
jQuery使用ajax_动力节点Java学院整理
2017/07/05 jQuery
详解Vue-Cli 异步加载数据的一些注意点
2017/08/12 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
2017/08/14 jQuery
JS鼠标3次点击事件实现代码及扩展思路
2017/09/12 Javascript
JS扩展String.prototype.format字符串拼接的功能
2018/03/09 Javascript
在vscode里使用.vue代码模板的方法
2018/04/28 Javascript
详解IOS微信上Vue单页面应用JSSDK签名失败解决方案
2018/11/14 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
2018/12/03 Javascript
以Python的Pyspider为例剖析搜索引擎的网络爬虫实现方法
2015/03/30 Python
Python 处理数据的实例详解
2017/08/10 Python
Python 获取中文字拼音首个字母的方法
2018/11/28 Python
海蓝之谜(LA MER)澳大利亚官方商城:全球高端奢华护肤品牌
2017/10/27 全球购物
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
意大利奢侈品综合电商网站:MODES
2019/12/14 全球购物
波兰多品牌运动商店:StreetStyle24.pl
2020/09/22 全球购物
汉语言文学毕业生求职信
2013/10/01 职场文书
五年级科学教学反思
2014/02/05 职场文书
群众路线教育实践活动调研报告
2014/11/03 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
先进党组织事迹材料
2014/12/26 职场文书
2016年村干部公开承诺书(公开承诺事项)
2016/03/25 职场文书
python实现web邮箱扫描的示例(附源码)
2021/03/30 Python
html form表单基础入门案例讲解
2021/07/15 HTML / CSS