一些关于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装饰器
Jun 15 Python
python中模块的__all__属性详解
Oct 26 Python
Python中装饰器学习总结
Feb 10 Python
Python3数据库操作包pymysql的操作方法
Jul 16 Python
Python实现动态添加属性和方法操作示例
Jul 25 Python
python3 requests库文件上传与下载实现详解
Aug 22 Python
python 遍历pd.Series的index和value
Nov 26 Python
python将数组n等分的实例
Dec 02 Python
python缩进长度是否统一
Aug 02 Python
Python matplotlib模块及柱状图用法解析
Aug 10 Python
Python 实现PS滤镜的旋涡特效
Dec 03 Python
virtualenv隔离Python环境的问题解析
Jun 21 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
php和nginx交互实例讲解
2019/09/24 PHP
jquery.ui.draggable中文文档
2009/11/24 Javascript
Prototype的Class.create函数解析
2011/09/22 Javascript
javascript教程之不完整的继承(js原型链)
2014/01/13 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
2014/10/08 Javascript
JavaScript 事件对象介绍
2015/04/13 Javascript
JS+CSS实现TreeMenu二级树形菜单完整实例
2015/09/18 Javascript
vue-dialog的弹出层组件
2020/05/25 Javascript
微信小程序中hidden不生效原因的解决办法
2017/04/26 Javascript
JavaScript设置名字输入不合法的实现方法
2017/05/23 Javascript
vue技术分享之你可能不知道的7个秘密
2018/04/09 Javascript
jQuery插件Validation表单验证详解
2018/05/26 jQuery
webpack项目轻松混用css module的方法
2018/06/12 Javascript
Angular4 Select选择改变事件的方法
2018/10/09 Javascript
vue数据操作之点击事件实现num加减功能示例
2019/01/19 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
javascript实现放大镜功能
2020/12/09 Javascript
浅析python3中的os.path.dirname(__file__)的使用
2018/08/30 Python
Python实现去除列表中重复元素的方法总结【7种方法】
2019/02/16 Python
深入解析python中的实例方法、类方法和静态方法
2019/03/11 Python
Django中使用 Closure Table 储存无限分级数据
2019/06/06 Python
python实现两张图片拼接为一张图片并保存
2019/07/16 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
Python要求O(n)复杂度求无序列表中第K的大元素实例
2020/04/02 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
关于Python3的import问题(pycharm可以运行命令行import错误)
2020/11/18 Python
python 模拟登陆github的示例
2020/12/04 Python
Python使用tkinter实现小时钟效果
2021/02/22 Python
css3强大的动画效果animate使用说明及浏览器兼容介绍
2013/01/09 HTML / CSS
基于IE10/HTML5 开发
2013/04/22 HTML / CSS
在校生党员自我评价
2013/09/25 职场文书
大学生职业生涯规划书范文
2014/01/14 职场文书
查摆剖析材料范文
2014/09/30 职场文书
2015年手术室工作总结
2015/05/11 职场文书
毕业论文答辩演讲稿
2015/06/23 职场文书
python cv2图像质量压缩的算法示例
2021/06/04 Python