摘要:装饰器介绍中的装饰器的目的是为一个目标函数添加额外的功能却不修改函数本身。装饰器的本身其实是一个特殊的函数。那么有啥更好的解决方式呢装饰器代码像上面这么写,可以较好地解决了上面提到的第一个问题。装饰器语法糖放在函数前面,相当于执行了等。
怎么理解python中的装饰器 一个比喻
知乎上有一个比较形象的比喻 https://www.zhihu.com/questio...:
人类穿着内裤很大程度上是为了遮羞和对关键部位进行保护,但是却不能提供保暖。因此我们还需要穿着长裤。长裤就是对内裤功能的补充,却不影响内裤本身的功能。
python中的装饰器的目的是为一个目标函数添加额外的功能却不修改函数本身。装饰器的本身其实是一个特殊的函数。主要的应用场景有插入日志,性能测试、事务处理等。
下面我们来举一个简单的例子一步一步了解一下。我们首先写了三个函数,即对两个数做加减乘的操作并打印:
def func_sum(x, y): print x+y def func_minus(x, y): print x - y def func_multiply(x, y): print x*y
但是我们现在有了新需求,就是需要在日志中打印所有加、减、乘操作时的时间。
import logging import time def func_sum(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) print x+y def func_minus(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) print x - y def func_multiply(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) print x*y
显然像上面这样修改每一个函数,在每一个函数中添加重复代码是不合适的。真正理想的是我们可以定义一个函数,专门用来输出日志,输出完日志后,再执行真正的函数。
import logging import time def func_sum(x, y): print x+y def func_minus(x, y): print x - y def func_multiply(x, y): print x*y def logging_first(func): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) return func logging_first(func_sum)(20,30)
但是上面这中实现方式也存在着种种问题。
log其实是logging_first(func_sum)时就打印了,而不是进行加、减、乘的时候打印的。
对加减乘函数的调用都需要修改成logging_first(func_sum)(20,30)类似方式。
那么有啥更好的解决方式呢?
import logging import time def func_sum(x, y): print x+y def func_minus(x, y): print x - y def func_multiply(x, y): print x*y def logging_first(func): def wrapper(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) return func(x, y) return wrapper logging_first(func_sum)(20, 30)
代码像上面这么写,可以较好地解决了上面提到的第一个问题。调用logging_first返回的是wrapper函数。执行wrapper函数的时候先打印log,然后马上执行了传入的func函数。
但是调用方式依旧需要修改成logging_first(func_sum)(20, 30)这种方式。
幸好,python给我们提供了优雅的语法糖。
我们可以将上面的代码修改成以下形式。
import logging import time def logging_first(func): def wrapper(x, y): logging.warning(time.strftime("%Y-%m-%d %H:%M:%S %Z", time.localtime(time.time()))) return func(x, y) return wrapper @logging_first def func_sum(x, y): print x + y @logging_first def func_minus(x, y): print x - y @logging_first def func_multiply(x, y): print x * y func_sum(20, 30) func_minus(20, 30) func_multiply(20, 30)
装饰器语法糖放在函数前面,相当于执行了logging_firts(func_sum)等。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/38250.html
摘要:前言最近跟着流畅的和学习,看到装饰器部分,有些头大倒不是因为概念难以理解,而是书和网上文章中有些地方有些矛盾之处在简单学习和实践之后,整理出我对装饰器的理解如下装饰器的定义在不同语境下,装饰器有不一样的含义,我大致认为有种定义一种把另一个对 前言 最近跟着《流畅的Python》和《Python Cookbook》学习,看到装饰器部分,有些头大倒不是因为概念难以理解,而是书和网上文章中有...
摘要:实现一个简单的装饰器输出被装饰函数的运行时间简单运用运行结果运行过程中,首先输出装饰器函数中的内容被装饰函数运行时间长度函数名称和实际参数计算结果然后得到最终的计算结果。 函数装饰器 函数装饰器用于在源码中标记函数, 以某种方式增强函数的行为,这是一个强大的功能。 函数装饰器是一个可调用对象,其参数是另外一个函数,即被装饰函数。装饰器可能处理被装饰函数,然后将其返回,或者将其替换成另一...
摘要:设计模式学习装饰器模式这个在我的笔记中有介绍工厂模式未完成,待更新单例模式保证一个对象最多只有一个实例存在。对安全性要求较高的场景,比如银行的修改余额业务。如果我们不使用单例模式,那么就会创建三个不同的实例。 设计模式学习 1.装饰器模式 这个在我的笔记中有介绍 2.工厂模式 author : liibntime :2018-11-6未完成,待更新 3.单例模式 保证一个对象最多只有一...
摘要:的装饰器可以实现在代码运行期间修改函数的上下文,即可以定义函数在执行之前进行何种操作和函数执行后进行何种操作,而函数本身并没有任何的改变。中的参数,实际上则是传递给实际上是的参数因为装饰器也是个函数,那么装饰器自己的能不能有参数传递呢。 Python的装饰器可以实现在代码运行期间修改函数的上下文, 即可以定义函数在执行之前进行何种操作和函数执行后进行何种操作, 而函数本身并没有任何的改...
阅读 2047·2019-08-30 15:52
阅读 2439·2019-08-29 18:37
阅读 789·2019-08-29 12:33
阅读 2838·2019-08-29 11:04
阅读 1521·2019-08-27 10:57
阅读 2091·2019-08-26 13:38
阅读 2759·2019-08-26 12:25
阅读 2444·2019-08-26 12:23