1.闭包函数

在看装饰器之前,我们先来搞清楚什么是闭包函数。python是一种面向对象的编程语言,在python中一切皆对象,这样就使得变量所拥有的属性,函数也同样拥有。

这样我们就可以理解在函数内创建一个函数的行为是完全合法的。

下面是一个简单的闭包例子:

# 定义一个函数def test(number_out):    # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个内部函数以及用到的一些变量称之为闭包

def test_in(number_in):        print("number_out:%d" % number_out)        print("in test_in 函数, number_in is %d" % number_in)        return number_out+number_in    # 其实这里返回的就是闭包的结果

return test_in# 给test函数赋值,这个20就是给参数number_outret = test(20)# 注意这里的100其实给参数number_inprint(ret(100))

运行结果:

闭包:即两个函数嵌套,外部函数返回内部函数的引用,外部函数一定会传入参数,外部函数起的是交换引用的作用.

闭包从语法上看非常简单,但是却有强大的作用。闭包可以将其自己的代码和作用域以及外部函数的作用结合在一起。

总结:什么函数可以被称为闭包函数呢?主要是满足两点:函数内部定义的函数;引用了外部变量但非全局变量。

2..什么是装饰器?

有了闭包函数的概念,我们再去理解装饰器会相对容易一些。python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象。装饰器函数的外部函数传入我要装饰的函数名字,返回经过修饰后函数的名字;内层函数(闭包)负责修饰被修饰函数。从上面这段描述中我们需要记住装饰器的几点属性,以便后面能更好的理解:

实质: 是一个函数

参数:是你要装饰的函数名(并非函数调用)

返回:是装饰完的函数名(也非函数调用)

作用:为已经存在的对象添加额外的功能

特点:不需要对对象做任何的代码上的变动

3.装饰器的作用

装饰器的作用: python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。

一般而言,我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改,但这种方法有弊端,因为修改原代码不能保证原代码的其他模块功能的有效性,而使用装饰器能完美解决这一问题。

python装饰器有很多经典的应用场景,比如:插入日志、性能测试、事务处理、权限校验等。装饰器是解决这类问题的绝佳设计。并且从引入中的列子中我们也可以归纳出:装饰器最大的作用就是对于我们已经写好的程序,我们可以抽离出一些雷同的代码组建多个特定功能的装饰器,这样我们就可以针对不同的需求去使用特定的装饰器,这时因为源码去除了大量泛化的内容而使得源码具有更加清晰的逻辑。

4.几种常用装饰器

4.1 函数的函数装饰器

我们以函数添加计时功能为例,讲述函数装饰器。

import timedef decorator(func):    def wrapper(*args, **kwargs):

start_time = time.time()

func()

end_time = time.time()        print(end_time - start_time)    return wrapper

@decorator  # @decorator 相当于 test = decorator(test)def test():

time.sleep(0.8)    print("test源代码")# 函数调用test()

在上面代码中 test是我要装饰器的函数,我想用装饰器显示test函数运行的时间。@decorator这个语法相当于 执行 test= decorator(test),为test函数装饰并返回。

再来看一下我们的装饰器函数  decorator,该函数的传入参数是func (即被装饰函数test的引用),返回参数是内层函数。这里的内层函数wrapper,其实就相当于闭包函数,它起到装饰给定函数的作用。

4.2 被装饰的函数有不定长参数

import timedef timefun(func):    def wrapped_func(*args, **kwargs):        print("%s called at %s" % (func.__name__, time.ctime()))

func(*args, **kwargs)    return wrapped_func

@timefundef foo(a, b, c, d="foo原代码"):

time.sleep(0.8)    print(a + b + c)    print(d)

foo(3, 5, 7)

运行结果:

wrapper参数为*args, **kwargs。 *args表示的参数以列表的形式传入;**kwargs表示的参数以字典的形式传入:

从图中我们可以看到:凡是以key=value形式的参数均存在kwargs中,剩下的所有参数都以列表的形式存于args中。这里要注意的是:为了不破坏原函数的逻辑,我们要保证内层函数wrapper_func和被装饰函数func的传入参数和返回值类型必须保持一致。

4.3. 类装饰器

前面我们提到的都是让 函数作为装饰器去装饰其他的函数或者方法,那么可不可以让 一个类发挥装饰器的作用呢?答案肯定是可以的,python中一切皆对象,函数和类本质没有什么不一样。

class Decorator(object):    def __init__(self, f):

self.f = f    def __call__(self):        print("decorator start")

self.f()        print("decorator end")

@Decoratordef func():    print("func")

func()

这里值得注意的是:__call__()是一个特殊方法,它可将一个类实例变成一个可调用对象:func = Decorator(func) # func是类Decorator的一个实例func() # 实现了__call__()方法后,func可以被调用

要使用类装饰器必须实现类中的__call__()方法,就相当于将实例变成了一个方法。

python装饰器作用-Python装饰器详解相关推荐

  1. axios拦截器作用及工作流程详解

    axios 拦截器 在请求或响应被then或catch处理之前拦截它们 作用: 主要是在axios请求和响应之前拦截请求和响应数据.拦截器有两种,请求拦截器一般会统一在请求头中添加token.响应拦截 ...

  2. python break语句作用_Python break语句详解

    Python break语句,就像在C语言中,打破了最小封闭for或while循环.break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句. bre ...

  3. python装饰器函数-Python函数装饰器常见使用方法实例详解

    本文实例讲述了Python函数装饰器常见使用方法.分享给大家供大家参考,具体如下: 一.装饰器 首先,我们要了解到什么是开放封闭式原则? 软件一旦上线后,对修改源代码是封闭的,对功能的扩张是开放的,所 ...

  4. python 生成器装饰器_对Python生成器、装饰器、递归的使用详解

    1.Python生成器表达式 1).Python生成器表达式 语法格式: (expr for iter_var in iterable) (expr for iter_var in iterable ...

  5. python装饰器详解-Python装饰器基础概念与用法详解

    本文实例讲述了Python装饰器基础概念与用法.分享给大家供大家参考,具体如下: 装饰器基础 前面快速介绍了装饰器的语法,在这里,我们将深入装饰器内部工作机制,更详细更系统地介绍装饰器的内容,并学习自 ...

  6. Python爬虫初级(十一)—— Selenium 详解

    欢迎关注公众号K的笔记阅读博主更多优质学习内容 上一篇内容:Python爬虫初级(九)-- ajax 详解 Selenium 库的安装 Selenium 的安装比起其他 python 库的安装稍显复杂 ...

  7. python中argparse模块关于 parse_args() 函数详解(全)

    目录 前言 1. 函数讲解 2. 基本用法 3. 实战讲解 前言 原理:命令行解析使用argparse包 作用:命令行传参赋值 可用在机器学习深度学习 或者 脚本运行等 了解这个函数需要了解其背后的原 ...

  8. pycharm导入python环境是空的_PyCharm导入python项目并配置虚拟环境的教程详解

    PyCharm导入python项目并配置虚拟环境的教程详解 进入PyCharm后,点击File→Open,然后在弹窗中选择需要导入项目的文件夹: 打开了python项目后,需要配置该项目对应的pyth ...

  9. python中时间戳、字符串之间转换详解

    [转载]python中时间戳.字符串之间转换详解 (2013-04-30 17:36:07) 转载▼ 标签: 转载 原文地址:python中时间戳.字符串之间转换详解作者:doris0920 1)秒数 ...

  10. python开发的程序中以电子表格显示数据_使用 Python 读取电子表格中的数据实例详解...

    Python 是最流行.功能最强大的编程语言之一.由于它是自由开源的,因此每个人都可以使用.大多数 Fedora 系统都已安装了该语言.Python 可用于多种任务,其中包括处理逗号分隔值(CSV)数 ...

最新文章

  1. thinkphp5中资源文件路径的使用
  2. 做外贸,独立B2C商城好,还是平台好
  3. v-viewer图片打不开一直在刷新_WordPress 上传图片时 async-upload.php出现520 Bug的原因及解决方案...
  4. CANopen笔记1
  5. MySql详解(六)
  6. php无符号整数转有符号整数,PHP中把有符号整型转换为无符号整型方法_PHP教程...
  7. Spring Security记住我功能之潜在的账号盗取风险
  8. Android 应用内更新 Support in-app updates [GP官方支持]
  9. 【codevs2952】 细胞分裂2,快速幂模版
  10. 结构体类型指针做函数参数(C++)
  11. 使用apktool.jar工具反编译和回编译Android APK 终端命令模式
  12. Maven 使用远程仓库错误
  13. linux 加入域 命令,Linux 加入域的最终完整版修改
  14. 一篇Chat(沉迷机器人操作系统(ROS)的一个理由和四种修仙秘籍)
  15. 可恢复保险丝特性测试
  16. 手机电池更换_红米note7pro电池更换实例注意事项
  17. 阿里云DTS订阅实现实时运营服务的方案及注意事项
  18. 机器学习服务活体检测算法荣获CFCA权威安全认证
  19. 多种多样的Photoshop 的撤消命令
  20. 西南联大数字复原项目获国际论坛奖项 百度AI赋予历史温度

热门文章

  1. python统计字符串中每个单词出现的次数_python中每个单词出现的次数是一组字符串?...
  2. 开发日记-20190509
  3. 时间序列数据库——索引用ES、聚合分析时加载数据用什么?docvalues的列存储貌似更优优势一些...
  4. python 属性可修改的装饰器 监控函数的运行时间
  5. Codeforces791:Ordinary Numbers题解
  6. java获取当前时间前一周、前一月、前一年的时间
  7. 安装gitlab并汉化
  8. ajax 和xmlHttpRequest区别
  9. 设计模式---(创建型)单例模式
  10. error: No resource identifier found for attribute ‘backIcon’ in package