本文实例讲述了python 自定义装饰器。分享给大家供大家参考,具体如下:
先看一个例子
def deco(func): print("before myfunc() called.") func() print("after myfunc() called.") return func @deco def myfunc(): print("myfunc() called.") # myfunc = deco(myfunc) # 与上面的@deco等价 myfunc() print("***********") myfunc()
会发现,输出为
before myfunc() called.
myfunc() called.
after myfunc() called.
myfunc() called.
***********
myfunc() called.
这就是说,装饰器里面的东西只调用了一次,为什么呢?
是因为,在myfunc()函数的定义前面加一句@deco,本质上完全等价于在出现def myfunc()后,先将下面所有内容的首地址传递给func,然后紧接着加上一句 myfunc = deco(myfunc)。执行这句话,表示func代表了本来定义的myfunc()的函数体,同时函数myfunc()的地址传递给deco()函数,即 myfunc -> func,这里就相当于myfunc的值与func的值完全相同了。然后执行装饰器里面的内容,最后返回给func,传递给myfunc。接下来在调用myfunc()的时候,打印输出“myfunc() called”。第二次调用myfunc()函数的时候,依然只打印输出“myfunc() called”。为什么第二次没有执行装饰器里面的内容呢?是因为,myfunc = deco(myfunc)这句话只执行了一次,而这句话,才是真正执行装饰器里面的内容的话。
上面的代码表示,装饰器相当于只对第一次调用他的函数进行了装饰,那么,怎么对每次调用的函数都装饰呢?接着看
def deco(func): def wrapper(*args, **kwargs): # *args, **kwargs用于接收func的参数 print("before myfunc() called.") func(*args, **kwargs) print("after myfunc() called.") return wrapper @deco def myfunc(a, b): print(a+b) # myfunc = deco(myfunc) # 与上面的@deco等价 myfunc(1, 2) print("***********") myfunc(3, 4)
该代码输出结果为
before myfunc() called.
3
after myfunc() called.
***********
before myfunc() called.
7
after myfunc() called.
我们说了,在myfunc()函数的定义前面加一句@deco,本质上完全等价于在出现def"htmlcode">
运行结果: wrapper的地址: <function deco.<locals>.wrapper at 0x0000023AA9FF58C8> 程序执行到myfunc(1,2)的时候,本质上是在执行wrapper(1, 2),于是先输出wrapper的地址,再执行func()函数。执行func()函数的时候,输出myfunc()的地址,(可见,此时myfunc的值与wrapper的是相等),再打印3。当输出func()函数的地址,可见func()函数的地址与myfunc()函数的地址不一样了!!!!这就是说,原来定义的myfunc()函数的函数体,已经属于func了,而不属于myfunc了!! 进一步见证奇迹!! 该代码没有任何输出。那是因为,执行myfunc(1, 2)的时候,本质上是执行wrapper(1, 2)。而wrapper(1, 2)又不干任何事情,所以没有输出。至于print(a+b)这句话,他的地址已经属于func了。 带参数的装饰器,可以参见其他文章 更多关于Python相关内容可查看本站专题:《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》 希望本文所述对大家Python程序设计有所帮助。
def deco(func):
def wrapper(*args, **kwargs): # *args, **kwargs用于接收func的参数
print("wrapper的地址:", wrapper)
func(*args, **kwargs)
print("func的地址:", func)
return wrapper
@deco
def myfunc(a, b):
print("myfunc的地址:",myfunc)
print(a+b)
# myfunc = deco(myfunc) # 与上面的@deco等价
myfunc(1, 2)
print("***********")
print("修改后myfunc的地址:",myfunc)
myfunc的地址: <function deco.<locals>.wrapper at 0x0000023AA9FF58C8>
3
func的地址: <function myfunc at 0x0000023AA9FF5840>
***********
修改后myfunc的地址: <function deco.<locals>.wrapper at 0x0000023AA9FF58C8>
def deco(func):
def wrapper(*args, **kwargs): # *args, **kwargs用于接收func的参数
pass
return wrapper
@deco
def myfunc(a, b):
print(a+b)
myfunc(1, 2)
python,自定义装饰器
更新日志
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]