在Python中函数也是一个对象,我们可以获得函数对象,然后执行函数

def func():
print('I am very good')
a = func
a

如果我们要是想增强这个函数呢?比如给它增加功能,在执行前输出一段log日志,表明函数名,但是呢又不想修改func函数的定义,这种在代码运行期间动态增加功能的方式,称之为"装饰器"。我们一步步来解析下它的作用。

按照上面的需求,输出log,可以这样做:

def func():
print('%s is running' % func.__name__)
print('I am very good') func()

但是这样做的话我们就修改了func函数的内部结构,所以不能这样,我们优化下:

def func():
print('I am very good') def use_logging(func):
print('%s is running' % func.__name__)
return func
a = use_logging(func)
a()

这样是可以解决问题的,但是如果func函数带参数的话怎么办呢?直接use_logging(func(a,b))? 肯定是不对的,这样的话传入的就是一个func函数执行完的结果,那就没办法在它执行前去增加操作了。所以还是要再包装优化下:

def use_logging(func):
def wrapper(*args, **kwargs):
print('%s is running' % func.__name__)
return func(*args, **kwargs)
return wrapper a = use_logging(func)
a(1, 2)

通过这样包装,得到一个func函数对象,它包含了func函数要做的事情,我们没有破坏它内部的结构。我们use_logging得到的是个wrapper函数对象,而可以通过给这个对象增加参数,从而func函数也可以有参数了,并且可以在func函数执行前增加我们需要的操作。

在Python中装饰器有这样的语法规则,我们不需要写a = use_logging(func) a(),我们只需要在func函数上面加个@use_logging,就可以完成这项工作。

def use_logging(func):
def wrapper(*args, **kwargs):
print('%s is running' % func.__name__)
return func(*args, **kwargs)
return wrapper @use_logging
def func(a, b):
print(a+b)
print('I am very good') func(1, 2)

然后我们正常使用func函数就可以了。在我的理解中装饰器就是对函数的一层层包装,注意是包装不是封装,封装的话是为了将冗余重复的代码消除而将这部分代码进行封装使用,包装的话是对一个函数方法内部不做更改而给它增加新的功能,对这个函数进行装饰。

人生苦短之Python装饰器的更多相关文章

  1. Python装饰器完全解读

    1 引言 装饰器(Decorators)可能是Python中最难掌握的概念之一了,也是最具Pythonic特色的技巧,深入理解并应用装饰器,你会更加感慨——人生苦短,我用Python. 2 初步理解装 ...

  2. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  3. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  4. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  5. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  6. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  7. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

  8. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

  9. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

随机推荐

  1. 邁向IT專家成功之路的三十則鐵律 鐵律二十三:IT人的成家之道-樸實

    根據內政部一份2013年最新的調查報告指出台灣人的離婚率位居全球第三,想想看如果這是經濟成長率的排名表現那該有多好.然而究竟為何在台灣這塊小小的土地上,不僅離婚非常高而且晚婚的人也非常的多,其原因肯定 ...

  2. android的窗口机制分析------UI管理系统

    Activity可以看做是整个Android系统的人机接口,它提供了一个窗口来绘制UI,每个Activity在启动时,我们都需要给它设置一个Content view,作为Activity所呈现的UI内 ...

  3. Node之父ry发布新项目deno:下一代Node

    https://mp.weixin.qq.com/s/1LcO3EqGV2iRlZ1aIrQeqw

  4. vue-class-component 以class的模式写vue组件

    vue英文官网推荐了一个叫vue-class-component的包,可以以class的模式写vue组件.vue-class-component(以下简称Component)带来了很多便利: 1.me ...

  5. odoo税金处理

    税金可以设置为'税金包含在价格中',或者'税金不包含在价格中'.         在税金计算处理过程中,odoo会将价格/金额按 total_included/ total_exincluded 分开 ...

  6. django 运行python manage.py sqlall books 时报错 app has migration

    出现这个问题的原因是版本之前的不兼容,我用的django版本是1.8.6 而 这条python manage.py sqlall books 是基于django1.0版本的. 在django1.8.6 ...

  7. JavaScript 内存机制

    简介 每种编程语言都有它的内存管理机制,比如简单的C有低级的内存管理基元,像malloc(),free().同样我们在学习JavaScript的时候,很有必要了解JavaScript的内存管理机制. ...

  8. caffe学习--Lenet5的应用和原理、实现----ubuntu16.04.2+caffe+mnist+train+test

    Lenet5的应用和原理.实现 ----------------------------------------------ubuntu16.04.2------------------------- ...

  9. 李洪强iOS开发之带placeHolder的Textview

    李洪强iOS开发之带placeHolder的Textview  01 - 创建工过程,定义全局属性,遵守textview的代理协议  02 - 添加一个textview和一个label 03 - 实现 ...

  10. Leetcode 001-twosum

    #Given an array of integers, return indices of the two numbers such that they add up to a specific t ...