一些关于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过滤txt文件内重复内容的方法
Oct 21 Python
对numpy中数组转置的求解以及向量内积计算方法
Oct 31 Python
python用插值法绘制平滑曲线
Feb 19 Python
解决python测试opencv时imread导致的错误问题
Jan 26 Python
使用python实现哈希表、字典、集合操作
Dec 22 Python
Python3 元组tuple入门基础
Feb 09 Python
Mysql数据库反向生成Django里面的models指令方式
May 18 Python
Python叠加矩形框图层2种方法及效果
Jun 18 Python
如何在 Matplotlib 中更改绘图背景的实现
Nov 26 Python
Python基础教程,Python入门教程(超详细)
Jun 24 Python
python模拟浏览器 使用selenium进入好友QQ空间并留言
Apr 12 Python
python垃圾回收机制原理分析
Apr 13 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之require/include顺序 推荐
2011/01/02 PHP
PHP执行shell脚本运行程序不产生core文件的方法
2016/12/28 PHP
jquery获取下拉列表的值为null的解决方法
2011/03/18 Javascript
JavaScript插件化开发教程 (一)
2015/01/27 Javascript
触屏中的JavaScript事件分析
2015/02/06 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
2015/05/28 Javascript
JS+CSS实现闪烁字体效果代码
2016/04/05 Javascript
js停止冒泡和阻止浏览器默认行为的简单方法
2016/05/15 Javascript
jQuery实现页面评论栏中访客信息自动填写功能的方法
2016/05/23 Javascript
浅谈JS中的bind方法与函数柯里化
2016/08/10 Javascript
详解Vue CLI3配置解析之css.extract
2018/09/14 Javascript
vue+element+Java实现批量删除功能
2019/04/08 Javascript
js中let能否完全替代IIFE
2019/06/15 Javascript
layui的select联动实现代码
2019/09/28 Javascript
[03:24]DOTA2超级联赛专访hao 大翻盘就是逆袭
2013/05/24 DOTA
跟老齐学Python之总结参数的传递
2014/10/10 Python
python实现简单http服务器功能
2018/09/17 Python
Python+PyQt5+MySQL实现天气管理系统
2020/06/16 Python
html5 移动端视频video的android兼容(去除播放控件、全屏)
2020/03/26 HTML / CSS
适合各种场合的美食礼品:Harry & David
2016/08/03 全球购物
外企C语言笔试题
2013/11/10 面试题
应届大学生自荐信
2013/12/05 职场文书
总经理岗位职责范本
2014/02/02 职场文书
厉行勤俭节约倡议书
2014/05/16 职场文书
求职信内容怎么写
2014/05/26 职场文书
房屋租赁授权委托书范本
2014/09/20 职场文书
关于运动会的广播稿50字
2014/10/17 职场文书
护理医院见习报告
2014/11/03 职场文书
2015年事业单位工作总结
2015/04/27 职场文书
老干部座谈会主持词
2015/07/03 职场文书
2015小学音乐教师个人工作总结
2015/07/21 职场文书
学生会部长竞选稿
2015/11/19 职场文书
Java中常用解析工具jackson及fastjson的使用
2021/06/28 Java/Android
Go语言基础map用法及示例详解
2021/11/17 Golang
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android
Win11电脑显示本地时间与服务器时间不一致怎么解决?
2022/04/05 数码科技