如何真正的了解python装饰器


Posted in Python onAugust 14, 2020

合理使用装饰器可以简化开发,并且使得代码更加清晰。下面我们分别介绍两种装饰器,不带参数的装饰器和带参数的装饰器。

一、不带参数的装饰器

我们用一个实际的例子来引入装饰器的概念,比如我们现在有一个方法A(),然后我们需要在方法A()执行之前在终端打印"function is running",这时候我们可以在方法A()的开始部分加上下面的代码:

print("function is running")

但是如果我们不想修改方法A()的代码,也可以重新写一个方法decorator(),然后把A()作为入参,代码如下:

def decorator(fun):
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        print("Method is running")
        return fun()
    return wrapper

python中的方法可以作为参数传入另一个方法,所以当我们执行decorator(A)的时候,返回的是一个方法,这个方法的本质是先执行print语句,然后再执行A()。

但是这样我们的调用代码就需要进行修改,也就是说之前调用方法A(),现在的写法是调用decorator(A)(),为了不影响调用的代码,我们使用python的语法糖改造方法A()的代码。

@decorator
def A():
    # do something

实际上只是在A()的前面加上一行@decorator,这样在我们的调用代码就不需要改变了。

装饰器中的@functools.wraps(fun)是为了保证返回的方法__name__属性和入参方法fun的__name__属性相同。

二、带入参的装饰器

在上面不带参数的装饰器中,我们实现了在执行方法A()之前打印一行固定的字符串,如果我们想要打印不同的字符串就需要用带参数的装饰器。实际上就是在不带参数的装饰器上再封装一层即可,代码如下:

def decorator_par(name):
    def decorator(fun):
        @functools.wraps(fun)
        def wrapper(*args, **kwargs):
            print("Method {} is running".format(name))
            return fun()
        return wrapper
    return decorator

这样我们就可以在使用装饰器的时候设置参数name,实现打印不同的信息。完整的代码如下:

import functools
 
def decorator_par(name):
    def decorator(fun):
        @functools.wraps(fun)
        def wrapper(*args, **kwargs):
            print("Method {} is running".format(name))
            return fun()
        return wrapper
    return decorator
 
@decorator_par("A")
def A():
    print("I am A")
 
@decorator_par("B")
def B():
    print("I am B")
 
A()
B()

执行输出为:

Method A is running
I am A
Method B is running
I am B

可以看到我们在不改变方法调用代码的情况下,实现了在该方法之前打印特定的信息。

以上就是装饰器的两种实现示例,实际开发中也可以将多个装饰器进行嵌套,可以实现更加复杂的需求。

内容扩展:

python函数式编程之装饰器

1.开放封闭原则

简单来说,就是对扩展开放,对修改封闭。

在面向对象的编程方式中,经常会定义各种函数。一个函数的使用分为定义阶段和使用阶段,一个函数定义完成以后,可能会在很多位置被调用。这意味着如果函数的定义阶段代码被修改,受到影响的地方就会有很多,此时很容易因为一个小地方的修改而影响整套系统的崩溃,所以对于现代程序开发行业来说,一套系统一旦上线,系统的源代码就一定不能够再改动了。然而一套系统上线以后,随着用户数量的不断增加,一定会为一套系统扩展添加新的功能。

此时,又不能修改原有系统的源代码,又要为原有系统开发增加新功能,这就是程序开发行业的开放封闭原则,这时就要用到装饰器了。

2.什么是装饰器

装饰器,顾名思义,就是装饰,修饰别的对象的一种工具。

所以装饰器可以是任意可调用的对象,被装饰的对象也可以是任意可调用对象。

3.装饰器的作用

在不修改被装饰对象的源代码以及调用方式的前提下为被装饰对象添加新功能。

以上就是如何真正的了解python装饰器的详细内容,更多关于你真的了解python装饰器么的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
探寻python多线程ctrl+c退出问题解决方案
Oct 23 Python
使用简单工厂模式来进行Python的设计模式编程
Mar 01 Python
python3实现UDP协议的服务器和客户端
Jun 14 Python
关于Python的一些学习总结
May 25 Python
python:接口间数据传递与调用方法
Dec 17 Python
python中实现控制小数点位数的方法
Jan 24 Python
Pandas统计重复的列里面的值方法
Jan 30 Python
pytorch使用指定GPU训练的实例
Aug 19 Python
python 公共方法汇总解析
Sep 16 Python
python集合删除多种方法详解
Feb 10 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
Jun 08 Python
Django实现WebSocket在线聊天室功能(channels库)
Sep 25 Python
详解python metaclass(元类)
Aug 13 #Python
MAC平台基于Python Appium环境搭建过程图解
Aug 13 #Python
Expected conditions模块使用方法汇总代码解析
Aug 13 #Python
深入了解Python装饰器的高级用法
Aug 13 #Python
python高级特性简介
Aug 13 #Python
Pytest如何使用skip跳过执行测试
Aug 13 #Python
matplotlib基础绘图命令之bar的使用方法
Aug 13 #Python
You might like
PHP错误抑制符(@)导致引用传参失败Bug的分析
2011/05/02 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
2014/01/03 PHP
destoon调用自定义模板及样式的公告栏
2014/06/21 PHP
在Windows XP下安装Apache+MySQL+PHP环境
2015/02/22 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
JQuery实现table行折叠效果以JSON做数据源
2014/05/26 Javascript
jQuery设置指定网页元素宽度和高度的方法
2015/03/25 Javascript
js实现精美的图片跟随鼠标效果实例
2015/05/16 Javascript
JQuery中层次选择器用法实例详解
2015/05/18 Javascript
JavaScript清空数组元素的两种方法简单比较
2015/07/10 Javascript
vue日期组件 支持vue1.0和2.0
2017/01/09 Javascript
Bootstrap学习笔记 轮播(Carousel)插件
2017/03/21 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
详解React+Koa实现服务端渲染(SSR)
2018/05/23 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
2018/07/09 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
2018/09/10 Javascript
js计算两个日期间的天数月的实例代码
2018/09/20 Javascript
详解Vue的常用指令v-if, v-for, v-show,v-else, v-bind, v-on
2018/10/12 Javascript
详解 微信小程序开发框架(MINA)
2019/05/17 Javascript
Python数据结构与算法(几种排序)小结
2019/06/22 Python
python GUI库图形界面开发之PyQt5动态加载QSS样式文件
2020/02/25 Python
解决Python中报错TypeError: must be str, not bytes问题
2020/04/07 Python
使用pyecharts1.7进行简单的可视化大全
2020/05/17 Python
Python实现播放和录制声音的功能
2020/08/12 Python
Python grpc超时机制代码示例
2020/09/14 Python
css3.0 图形构成实例练习一
2013/03/19 HTML / CSS
Html5大文件断点续传实现方法
2015/12/05 HTML / CSS
加拿大票务网站:Ticketmaster加拿大
2017/07/17 全球购物
Opodo英国旅游网站:预订廉价航班、酒店和汽车租赁
2018/07/14 全球购物
日本酒店、民宿、温泉旅馆、当地旅行团中文预订:e路东瀛
2019/12/09 全球购物
农村党支部书记司法四风问题对照检查材料
2014/09/26 职场文书
副校长个人对照检查材料思想汇报
2014/10/04 职场文书
三八节活动主持词
2015/07/04 职场文书
幼儿园小朋友毕业感言
2015/07/30 职场文书
2019年大学毕业生个人自我鉴定范文大全
2019/03/21 职场文书
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python