一些关于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自动化测试之setUp与tearDown实例
Sep 28 Python
Python入门篇之条件、循环
Oct 17 Python
简单了解Python下用于监视文件系统的pyinotify包
Nov 13 Python
Python自定义主从分布式架构实例分析
Sep 19 Python
python flask实现分页效果
Jun 27 Python
基于Python __dict__与dir()的区别详解
Oct 30 Python
Python logging管理不同级别log打印和存储实例
Jan 19 Python
Python使用分布式锁的代码演示示例
Jul 30 Python
pycharm执行python时,填写参数的方法
Oct 29 Python
浅析python参数的知识点
Dec 10 Python
python 采用paramiko 远程执行命令及报错解决
Oct 21 Python
使用pytorch实现可视化中间层的结果
Dec 30 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
DC动漫人物排行
2020/03/03 欧美动漫
关于php程序报date()警告的处理(date_default_timezone_set)
2013/10/22 PHP
php使用GD库创建图片缩略图的方法
2015/06/10 PHP
用PHP生成excel文件到指定目录
2015/06/22 PHP
PHP中的Trait 特性及作用
2016/04/03 PHP
php插入含有特殊符号数据的处理方法
2016/11/24 PHP
a标签的css样式四个状态
2021/03/09 HTML / CSS
Javascript 类型转换方法
2010/10/24 Javascript
一个js过滤空格的小函数
2014/10/10 Javascript
使用js实现数据格式化
2014/12/03 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
js阻止冒泡和默认事件(默认行为)详解
2016/10/20 Javascript
Javascript实现倒计时时差效果
2017/05/18 Javascript
JS实现下拉菜单列表与登录注册弹窗效果
2017/08/10 Javascript
JavaScript中递归实现的方法及其区别
2017/09/12 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
2018/08/19 Javascript
基于Vue 实现一个中规中矩loading组件
2019/04/03 Javascript
vue和better-scroll实现列表左右联动效果详解
2019/04/29 Javascript
基于VUE的v-charts的曲线显示功能
2019/10/01 Javascript
[48:54]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第二场 6.3
2018/06/04 DOTA
python清除字符串前后空格函数的方法
2018/10/21 Python
python 发送和接收ActiveMQ消息的实例
2019/01/30 Python
python登录WeChat 实现自动回复实例详解
2019/05/28 Python
python将字典列表导出为Excel文件的方法
2019/09/02 Python
python getpass实现密文实例详解
2019/09/24 Python
python代码打印100-999之间的回文数示例
2019/11/24 Python
解决pycharm修改代码后第一次运行不生效的问题
2021/02/06 Python
健身场所或家用健身设备:Life Fitness
2017/11/01 全球购物
农场厂长岗位职责
2013/12/28 职场文书
正科级干部考察材料
2014/05/29 职场文书
本科生自荐信
2014/06/18 职场文书
自我介绍演讲稿范文
2014/08/21 职场文书
交通事故赔偿协议书怎么写
2014/10/04 职场文书
2015入党个人自传范文
2015/06/26 职场文书
幼儿园开学家长寄语(2016春季)
2015/12/03 职场文书
《抽屉原理》教学反思
2016/02/20 职场文书