一些关于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 装饰器功能以及函数参数使用介绍
Jan 27 Python
进一步了解Python中的XML 工具
Apr 13 Python
讲解Python中的标识运算符
May 14 Python
利用python程序生成word和PDF文档的方法
Feb 14 Python
django传值给模板, 再用JS接收并进行操作的实例
May 28 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
Feb 16 Python
python 计算平均平方误差(MSE)的实例
Jun 29 Python
python cumsum函数的具体使用
Jul 29 Python
numpy中三维数组中加入元素后的位置详解
Nov 28 Python
Django QuerySet查询集原理及代码实例
Jun 13 Python
python批量创建变量并赋值操作
Jun 03 Python
python 常用的异步框架汇总整理
Jun 18 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更新修改excel中的内容实例代码
2014/02/26 PHP
模板引擎smarty工作原理以及使用示例
2014/05/25 PHP
PHP堆栈调试操作简单示例
2018/06/15 PHP
PHP面向对象程序设计之构造方法和析构方法详解
2019/06/13 PHP
PHP代码加密的方法总结
2020/03/13 PHP
DOMAssitant最新版 DOMAssistant 2.5发布
2007/12/25 Javascript
jQuery解析XML与传统JavaScript方法的差别实例分析
2015/03/05 Javascript
浅谈javascript中replace()方法
2015/11/10 Javascript
JavaScript知识点总结(五)之Javascript中两个等于号(==)和三个等于号(===)的区别
2016/05/31 Javascript
JavaScript trim 实现去除字符串首尾指定字符的简单方法
2016/12/27 Javascript
Angular 2父子组件数据传递之@Input和@Output详解 (上)
2017/07/05 Javascript
Angular利用内容投射向组件输入ngForOf模板的方法
2018/03/05 Javascript
详解vue-cli项目中怎么使用mock数据
2018/05/29 Javascript
JS+php后台实现文件上传功能详解
2019/03/02 Javascript
一步快速解决微信小程序中textarea层级太高遮挡其他组件
2019/03/04 Javascript
详解JS实现简单的时分秒倒计时代码
2019/04/25 Javascript
Node.js中出现未捕获异常的处理方法
2020/06/29 Javascript
JavaScript文档加载模式以及元素获取
2020/07/28 Javascript
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
2014/11/18 Python
初步探究Python程序的执行原理
2015/04/11 Python
如何利用Fabric自动化你的任务
2016/10/20 Python
Python实现基本数据结构中栈的操作示例
2017/12/04 Python
django 自定义filter 判断if var in list的例子
2019/08/20 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
用python介绍4种常用的单链表翻转的方法小结
2020/02/24 Python
PyQt5实现画布小程序
2020/05/30 Python
python爬虫分布式获取数据的实例方法
2020/11/26 Python
tensorflow与numpy的版本兼容性问题的解决
2021/01/08 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
初中化学教学反思
2014/01/23 职场文书
网上开店必备创业计划书
2014/01/26 职场文书
幼儿园保教管理制度
2014/02/03 职场文书
推荐信怎么写
2014/05/09 职场文书
火灾现场处置方案
2014/05/28 职场文书
古诗之感恩老师
2019/10/24 职场文书