所不为人知的Python装饰器
装饰器可以说是Python中非常重要的特性之一。有些人要么从没使用过装饰器,要么就是对装饰器的使用一知半解。也有些人觉得装饰器很简单:"装饰器不就是那些把函数作为参数并输出一个函数的函数"。这里介绍一些装饰器“所不为人知”的一些地方。
先回顾一下函数。函数在python中是一等公民,也就是说,函数也是对象,它可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值、也有属性。
例如:
1.1.输出函数f的所有属性
def f():
print('something')
print(dir(f))
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
1.2.赋值给一个变量g
g = f
g()
something
1.3.作为参数传递给其他函数
def func_name(function):
return function.__name__
func_name(f)
f
1.4.作为元素添加到集合对象list中
function_collection = [f, g]
for function in function_collection:
function()
something
something
装饰器常常被描述成“装饰器就是那些把函数作为参数并输出一个函数的函数”,严格地讲,这并不是很准确。其实,他还有如下一些细节:
- 在函数定义的时候就执行了一次装饰器的装饰过程
- 用
@d
装饰一个函数定义x,等价于,先定义函数x,然后执行x=d(x) - 用
@d和
装饰一个函数定义x,等价于,先定义函数x,然后执行x=e(d(x))@e
举几个例子会更加让人理解。
def print_when_called(function):
def new_function(*args, **kwargs):
print("{} was called".format(function.__name__))
return function(*args, **kwargs)
return new_function def one():
return 1
one = print_when_called(one) @print_when_called
def two():
return 2 [one(), two(), one(), two()]
one was called
two was called
one was called
two was called
[1, 2, 1, 2]
你可能会注意到,上面的输出是在执行[one(), two(), one(), two()]后才打印出来,实际上,在one()或two()执行前,print_when_called
就已经返回了负责打印的new_function。下面的例子会更容易理解些:
def print_when_applied(function):
print("print_when_applied was applied to {}".format(function.__name__))
return function @print_when_applied
def never_called():
print("never_called")
print_when_applied was applied to never_called
显而易见,“never_called”没有被执行,但是“print_when_applied was applied to never_called”已经打印出来了。
下面再说一下装饰器执行的顺序。
@print_when_applied
@print_when_called
def this_name_will_be_printed_when_called_but_not_at_definition_time():
pass
this_name_will_be_printed_when_called_but_not_at_definition_time()
print_when_applied was applied to new_function
this_name_will_be_printed_when_called_but_not_at_definition_time was calle
所不为人知的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装饰器与面向切面编程
今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...
随机推荐
- BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4987 Solved: 1732[Submit][Stat ...
- stl总结精简版
STL 精简版 vetor #include<vector> #include<cstdio> #include<algorithm> #include<io ...
- 2017ecjtu-summer training #1 UVA 10399
It has been said that a watch that is stopped keeps better time than one that loses 1 second per day ...
- javascript数据类型及转换
此篇数据类型和转换只限于ECMA规范,规范用了比较大的篇幅讲数据类型和类型转换,理解了这个最基本的概念对表达式.语句.执行环境.对象及继承都有非常大的帮助,遂整理如下: 数据类型和值 类型转换 表达式 ...
- hbase性能优化总结
hbase性能优化总结 1. 表的设计 1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都 ...
- nginx.conf文件
user www www; worker_processes auto; error_log /home/wwwlogs/nginx_error.log crit; pid /us ...
- Struts2与Ajax数据交互
写在前面: ajax请求在项目中常常使用,今天就平时掌握的总结一下,关于使用ajax请求到Struts2中的action时,前台页面与后台action之间的数据传递交互问题. 这里我主要记录下自己所掌 ...
- 人人都是CEO
在这个互联网崛起的时代有些流行说法,比如:人人都是产品经理,人人都是程序员以突显行业繁荣的特点,但从更基本的出发点,难道人人不都是 CEO 么?个人的 CEO. 从这个名字套路出发,我沿着想了下去,作 ...
- shopnc前台登陆不进去解决方法
安装好shopnc后,注册新用户成功,且登陆后提示登陆成功,但是一两秒后自动跳转回登陆页面,需要重新登陆问题 PHP写session不是自动起的,需要修改后才行,所以 找到PHP的php.ini配置文 ...
- Go_Hello word
与Go相关直接命令有哪些? go get 获取远程包 go run 直接运行程序 go bulid 测试编译 go fmt 格式化代码 go install 编译包文件 ...