一些关于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基础教程之popen函数操作其它程序的输入和输出示例
Feb 10 Python
Python动态加载模块的3种方法
Nov 22 Python
python使用BeautifulSoup分析网页信息的方法
Apr 04 Python
Python实现堆排序的方法详解
May 03 Python
浅析使用Python操作文件
Jul 31 Python
Windows下的Jupyter Notebook 安装与自定义启动(图文详解)
Feb 21 Python
Anaconda入门使用总结
Apr 05 Python
详解将Django部署到Centos7全攻略
Sep 26 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
Mar 04 Python
python 写函数在一定条件下需要调用自身时的写法说明
Jun 01 Python
Python虚拟环境的创建和使用详解
Sep 07 Python
详解python 条件语句和while循环的实例代码
Dec 28 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
laravel安装和配置教程
2014/10/29 PHP
tp5(thinkPHP5)框架实现多数据库查询的方法
2019/01/10 PHP
struts2 jquery 打造无限层次的树
2009/10/23 Javascript
用JavaScript对JSON进行模式匹配 (Part 2 - 实现)
2010/07/17 Javascript
jQuery 追加元素的方法如append、prepend、before
2014/01/16 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
实现音乐播放器的代码(html5+css3+jquery)
2015/08/04 Javascript
快速学习JavaScript的6个思维技巧
2015/10/13 Javascript
JavaScript常用数组算法小结
2016/02/13 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
js实现tab选项卡切换功能
2017/01/13 Javascript
各种选择框jQuery的选中方法(实例讲解)
2017/06/27 jQuery
纯js实现的积木(div层)拖动功能示例
2017/07/19 Javascript
AngularJS中filter的使用实例详解
2017/08/25 Javascript
tracking.js页面人脸识别插件使用方法
2020/04/16 Javascript
vue离开当前页面触发的函数代码
2020/09/01 Javascript
js实现随机点名
2021/01/19 Javascript
python数据库操作常用功能使用详解(创建表/插入数据/获取数据)
2013/12/06 Python
Python编写屏幕截图程序方法
2015/02/18 Python
python实现通过pil模块对图片格式进行转换的方法
2015/03/24 Python
Python语言实现机器学习的K-近邻算法
2015/06/11 Python
Python 实现淘宝秒杀的示例代码
2018/01/02 Python
快速解决安装python没有scripts文件夹的问题
2018/04/03 Python
Python3 安装PyQt5及exe打包图文教程
2019/01/08 Python
Django实现跨域请求过程详解
2019/07/25 Python
Pytorch中accuracy和loss的计算知识点总结
2019/09/10 Python
Python对接 xray 和微信实现自动告警
2019/09/17 Python
利用CSS3 动画 绘画 圆形动态时钟
2018/03/20 HTML / CSS
初任培训自我鉴定
2013/10/07 职场文书
自荐信格式写作方法有哪些呢
2013/11/20 职场文书
父母寄语大全
2014/04/12 职场文书
车间安全生产标语
2014/06/06 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
实习推荐信格式模板
2015/03/27 职场文书
2015年统战工作总结
2015/05/19 职场文书
java设计模式--七大原则详解
2021/07/21 Java/Android