所不为人知的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装饰器与面向切面编程
今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...
随机推荐
- Ajax方式分页加载列表实现
在前面: 最近需要用到这个功能,所以这几天一直在研究这个,目前大致功能已实现,后续需要完善,但需要的功能点已完成,记录下: 1.分页功能引入bootstrap的分页插件: <script typ ...
- Linux批量处理文件脚本
Linux shell字符串截取与拼接 一 Linux 的字符串截取很有用.有八种方法. 假设有变量 var=http://www.linuxidc.com/123.htm 1 # 号截取,删除左边 ...
- 【margin和padding的区别】
margin和padding的区别 margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离.(外边距) padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离.(内 ...
- C++ STL之min_element()与max_element()(取容器中的最大最小值)
min_element()和max_element 头文件:#include<algorithm> 作用:返回容器中最小值和最大值.max_element(first,end,cmp);其 ...
- hdu_1573 X问题(不互素的中国剩余定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1573 X问题 Time Limit: 1000/1000 MS (Java/Others) Me ...
- hbmy周赛1--D
D - Toy Cars Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Submi ...
- c语言基础学习02_windows系统下的cmd命令
=============================================================================注意:cmd的命令很多,需要用的时候可以查询即 ...
- Windows系统下文件的概念及c语言对其的基本操作(乙)
- EMC题
[面试题]EMC易安信面试题解 1. 除以59的余数是多少. 来自wiki:费马小定理是数论中的一个定理:假如a是一个整数,p是一个質数,那么 如果a不是p的倍数,这个定理也可以写成 这个书写方式更加 ...
- 在vue-cli项目中使用echarts
这个示例使用 vue-cli 脚手架搭建 安装echarts依赖 npm install echarts -S 或者使用国内的淘宝镜像: 安装 npm install -g cnpm --regist ...