【转】python装饰器
什么是装饰器?
python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能。
这个函数的特殊之处在于它的返回值也是一个函数,这个函数是内嵌“原“”函数的函数。
一般而言,我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改,例如:
import time
def f():
print("hello")
time.sleep(1)
print("world")
这是我们最原始的的一个函数,然后我们试图记录下这个函数执行的总时间,那最简单的做法就是改动原来的代码:
import time
def f():
start_time = time.time()
print("hello")
time.sleep(1)
print("world")
end_time = time.time() execution_time = (end_time - start_time)*1000
print("time is %d ms" %execution_time)
但是实际工作中,有些时候核心代码并不可以直接去改,所以在不改动原代码的情况下,我们可以再定义一个函数。(但是生效需要再次执行函数)
import time def deco(func):
start_time = time.time()
f()
end_time = time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" %execution_time) def f():
print("hello")
time.sleep(1)
print("world") if __name__ == '__main__': deco(f)
print("f.__name__ is",f.__name__)
print()
这里我们定义了一个函数deco,它的参数是一个函数,然后给这个函数嵌入了计时功能。但是想要拓展这一千万个函数功能,
就是要执行一千万次deco()函数,所以这样并不理想!接下来,我们可以试着用装饰器来实现,先看看装饰器最原始的面貌。
import time def deco(f):
def wrapper():
start_time = time.time()
f()
end_time = time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" %execution_time )
return wrapper @deco
def f():
print("hello")
time.sleep(1)
print("world") if __name__ == '__main__':
f()
这里的deco函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。
其中作为参数的这个函数f()就在返回函数wrapper()的内部执行。然后在函数f()前面加上@deco,
f()函数就相当于被注入了计时功能,现在只要调用f(),它就已经变身为“新的功能更多”的函数了,
(不需要重复执行原函数)。
扩展1:带有固定参数的装饰器
import time def deco(f):
def wrapper(a,b):
start_time = time.time()
f(a,b)
end_time = time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" % execution_time)
return wrapper @deco
def f(a,b):
print("be on")
time.sleep(1)
print("result is %d" %(a+b)) if __name__ == '__main__':
f(3,4)
扩展2:无固定参数的装饰器
import time def deco(f):
def wrapper(*args, **kwargs):
start_time = time.time()
f(*args, **kwargs)
end_time = time.time()
execution_time_ = (end_time - start_time)*1000
print("time is %d ms" %execution_time)
return wrapper @deco
def f(a,b):
print("be on")
time.sleep(1)
print("result is %d" %(a+b)) @deco
def f2(a,b,c):
print("be on")
time.sleep(1)
print("result is %d" %(a+b+c)) if __name__ == '__main__':
f2(3,4,5)
f(3,4)
扩展3:使用多个装饰器,装饰一个函数
import time def deco01(f):
def wrapper(*args, **kwargs):
print("this is deco01")
start_time = time.time()
f(*args, **kwargs)
end_time = time.time()
execution_time = (end_time - start_time)*1000
print("time is %d ms" % execution_time)
print("deco01 end here")
return wrapper def deco02(f):
def wrapper(*args, **kwargs):
print("this is deco02")
f(*args, **kwargs) print("deco02 end here")
return wrapper @deco01
@deco02
def f(a,b):
print("be on")
time.sleep(1)
print("result is %d" %(a+b)) if __name__ == '__main__':
f(3,4)
'''
this is deco01
this is deco02
hello,here is a func for add :
result is 7
deco02 end here
time is 1003 ms
deco01 end here
'''
装饰器调用顺序:
饰器是可以叠加使用的,那么使用装饰器以后代码是啥顺序呢?
对于Python中的”@”语法糖,装饰器的调用顺序与使用 @ 语法糖声明的顺序相反。
在这个例子中,”f(3, 4) = deco01(deco02(f(3, 4)))”。
Python内置装饰器
在Python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod 和property。
- staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用
- classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
- property 是属性的意思,表示可以通过通过类实例直接访问的信息
对于staticmethod和classmethod这里就不介绍了,通过一个例子看看property。

注意,对于Python新式类(new-style class),如果将上面的 “@var.setter” 装饰器所装饰的成员函数去掉,则Foo.var 属性为只读属性,使用 “foo.var = ‘var 2′” 进行赋值时会抛出异常。但是,对于Python classic class,所声明的属性不是 read-only的,所以即使去掉”@var.setter”装饰器也不会报错。
【转】python装饰器的更多相关文章
- 关于python装饰器
关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...
- python装饰器通俗易懂的解释!
1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...
- Python 装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
- python 装饰器修改调整函数参数
简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...
- python 装饰器学习(decorator)
最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- 关于python装饰器(Decorators)最底层理解的一句话
一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...
- Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- Python装饰器与面向切面编程
今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...
- python装饰器方法
前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...
随机推荐
- 在一个C程序中,main()函数可以放在哪?
C语言规定,在一个C程序中,main()函数的位置(). A.必须在系统调用的库函数之后 B.必须在程序的开始 C.必须在程序的最后 D.可以在任意位置 答案:D [解析] 每个C程序有且只有一个主函 ...
- layuiAdmin std v1.x 【iframe版】开发者文档
layuiAdmin pro v1.x [单页版]开发者文档 layuiAdmin.std(iframe 版) 是完全基于 layui 架构而成的通用型后台管理模板系统,采用传统的 iframe 多页 ...
- Intellij Idea2019版本激活,目前可以激活到2089,解决失效问题(非商业用途)
目录 Intellij Idea2019版本激活,目测可以激活到2089!! 前言-此教程仅用作个人学习,请勿用于商业获利,造成后果自负!!! 步骤(直接激活新下载的) 成功 注意(不想重新下载的小伙 ...
- HTML连载59-子绝父相
一.子绝父相 1.只使用相对定位,对图片的位置进行精准定位. <!DOCTYPE html> <html lang="en"> <head> & ...
- sshpass远程登陆
1,ssh ssh 端口为默认22的时候: sshpass -p 888888 scp -o StrictHostKeyChecking=no /root/images.zip root@21.1.9 ...
- Java进阶学习(1)之类与对象(上)
package com.study; //自动售卖机 public class vmachine { private int price = 80; private int balance; priv ...
- as中怎么下载更新platforms和build-tools
链接:https://blog.csdn.net/sunbinkang/article/details/78632652
- ${var}与$var的区别,个人总结的看法
${var} set variable 123 ${var}类似于变量值,相当于123 $var类似于变量名,指向对应的存储位置,相当于“123”,一般只有在rf关键字为断言的如“should be ...
- 分布式事务 --- CAP 理论
本文部分来自参考资料!!半原创 概述 介绍CAP理论,并简单地证明了三存二的定论. CAP 理论 1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标.分别为 : C ...
- SpringCloud全家桶学习之断路器---Hystrix(五)
目前我也在摸索着学习Spring Cloud,本节主要摸索的是服务熔断.服务降级.Hystrix服务监控. 一.Hystrix概述 (1)服务雪崩 服务雪崩:多个微服务之间调用的时候,假设微服务A调用 ...