装饰器本身是个函数

import time
def log(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("The func '{}' used {}s.".format(func.__name__, end-start))
return result
return wrapper

这一个装饰器,当我们这样使用时

@log
def fuck(name):
"""Fuck someone"""
print("Fuck", name)
它只是执行了fuck = log(fuck)这样一句代码而已。
也就是说,我们表面上是用fuck("myself"),事实上执行的都是log(fuck)("myself")。因为Python里面都是对象嘛。
同样的道理,假设我们定义了一个带参数的装饰器logging,它实际上执行的是
func = logging(arguments)(func)

也就是上面那个不带参数的装饰器多定义一层就行了。

import time
def logging(arguments):
def log(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("The func '{}' used {}s.".format(func.__name__, end-start))
return result
return wrapper
# do something
return log

但,当我们使用一个装饰器之后,它会将原本的函数元信息给覆盖掉。譬如:函数名称,函数文档等等。
例如上例

print(fuck.__name__)
print(fuck.__doc__)

你会发现,函数信息全部没了!fuck它不叫fuck,改名叫wrapper了。它的文档也变成了none
解决办法很简单,定义装饰器的时候用warps装饰器装饰接受原函数参数的那一层就行了。
这个来自functools模块的装饰器能帮你复制函数的元信息到被绑定的函数身上。

修改装饰器如下(其实就加了一行代码hhh)

import time
from functools import wraps
def log(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("The func '{}' used {}s.".format(func.__name__, end-start))
return result
return wrapper

当我们再运行

print(fuck.__name__)
print(fuck.__doc__)

就能看到函数的的元信息没变了。

  • 装饰器定义时加@wraps是个好习惯。

Python装饰器 [1]的更多相关文章

  1. 关于python装饰器

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

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

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

  3. Python 装饰器学习

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

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

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

  5. python 装饰器学习(decorator)

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

  6. Python装饰器详解

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

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

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

  8. Python装饰器由浅入深

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

  9. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  10. python装饰器方法

    前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...

随机推荐

  1. Redis 持久化之RDB和AOF

    Redis 持久化之RDB和AOF Redis 有两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File).如果你想快速了解和使用RDB和AOF,可以直 ...

  2. python文件

    目录 1. 文件的概念 1.1 文件的概念和作用 1.2 文件的存储方式 2. 文件的基本操作 2.1 操作文件的套路 2.2 操作文件的函数/方法 2.3 read 方法 -- 读取文件 2.4 打 ...

  3. 有哪些Java性能优化方法?

    面试官:"有性能优化经验没?"  应聘者:"有一点."   面试官:"那你们从哪些方面做了优化?"   应聘者:"sql优化.JV ...

  4. netty入门demo(一)

    目录 前言 正文 代码部分 服务端 客服端 测试结果一: 解决粘包,拆包的问题 总结 前言 最近做一个项目: 大概需求: 多个温度传感器不断向java服务发送温度数据,该传感器采用socket发送数据 ...

  5. jQuery 事件 - ready() 方法

    转载:http://www.w3school.com.cn/jquery/jquery_hide_show.asp 实例 在文档加载后激活函数: $(document).ready(function( ...

  6. git 代码服务器的网页版gitweb的搭建

    sudo apt-get install apache2 git-core gitwebsudo a2enmod rewrite #vi /etc/gitweb.conf $projectroot = ...

  7. Docker EE 安装 on centos7

    本文演示如何在CentOS7上安装Docker EE. 1 安装方式 有两种方法可以 在Centos上安装和升级Docker企业版(Docker EE): YUM存储库:设置Docker存储库并从中安 ...

  8. 产品经理说| AIOps 让告警变得更智能 (下)

    AIOps 人工智能和IT运营支撑 Ops 之间的故事,愈演愈烈,已经成为当今运维圈的热门话题,我打算从2篇文档分享我们在 AIOps 上一些探索和实践.(上篇)主要介绍了为什么事件(告警)处理需要 ...

  9. Keras实现VGG16

    一.代码实现 # -*- coding: utf-8 -*- """ Created on Sat Feb 9 15:33:39 2019 @author: zhen & ...

  10. perfect-scrollbar在vue中的使用

    1.下载perfect-scrollbar依赖包 npm install perfect-scrollbar 2.perfect-scrollbar特性 1)直接下载依赖包及包含css样式和js 2) ...