众所周知,Python3 有一个符号,叫做 @
,意为装饰器,具体过程如下:
@demo
def func():
...
# <=>
def func():
...
func = demo(func)
可以对 func
改进:
def demo(func):
def new_func():
func()
print('func used')
return new_func
@demo
def func():
print('hello')
运行结果:
hello
func used
(@
后面可以为任何可调用对象,被装饰的可以是函数或类,具体在这里不在详细赘述,感兴趣的可以上网查查看)
一、“立即”装饰器
这个名字是我自己取的,如有想法,欢迎在评论区留言!
# @lambda _: _()
def hello() -> str:
return 'hello'
print(hello)
print(hello())
输出:
<function hello at 0xbalabala>
hello
这里 0xbalabala 不是真的 balabala,是 hello
的地址
@lambda _: _()
def hello() -> str:
return 'hello'
print(hello)
# print(hello()) # 报错,因为 hello 是个 str,而 str 对象不可调用
输出 hello
可以看出,被 @lambda _: _()
的函数/类变成了调用自己的结果
二、套娃装饰器
既然装饰完还是函数,那么,我们就可以再装饰一遍:
def demo(func):
def new_func():
return func() * 2
return new_func
@demo
@demo
def func():
return 1
print(func())
输出4
既然装饰器也是函数,那么,我们就可以给装饰器装饰两遍:
def dedemo(demo):
def new_demo(func):
return demo(demo(func))
return new_demo
@dedemo
@dedemo
def demo(func):
def new_func():
return func() * 2
return new_func
@demo
@demo
def func():
return 1
print(func())
这样,输出28!
既然给装饰器装饰的装饰器也是函数,那么,手动dedemo = dedemo(dedemo)
,不对,dedemo = dedemo(dedemo(dedemo))
两次!
def dedemo(demo):
def new_demo(func):
return demo(demo(func))
return new_demo
dedemo = dedemo(dedemo(dedemo))
dedemo = dedemo(dedemo(dedemo))
@dedemo
@dedemo
def demo(func):
def new_func():
return func() * 2
return new_func
@demo
@demo
def func():
return 1
print(func())
运行,输出————
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
main()
File "<pyshell#31>", line 16, in main
def func():
File "<pyshell#31>", line 4, in new_demo
return demo(demo(func))
File "<pyshell#31>", line 4, in new_demo
return demo(demo(func))
File "<pyshell#31>", line 4, in new_demo
return demo(demo(func))
[Previous line repeated 1021 more times]
RecursionError: maximum recursion depth exceeded
你不要妄想修改递归最大深度,因为时 间 超 限
那么,到底会输出多少呢?
dedemo = dedemo(dedemo(dedemo))
让demo的效果变成原来的两倍的两倍,也就是
def dedemo(demo):
def new_demo(func):
return demo(demo(demo(demo(demo(demo(demo(demo(func)))))))) # 8 个 demo
return new_demo
dedemo = dedemo(dedemo(dedemo))
让demo的效果变成原来的八倍的八倍,也就是
def dedemo(demo):
def new_demo(func):
return demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(demo(func)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) # 2 ** 9 个 demo
return new_demo
那么,@dedemo def demo
就变成了func() * 2 ** 9
,
两次就变成了func() * (2 ** 9) ** 2
;
@demo def func
就变成了(2 ** 9) ** 2
,
两次就变成了((2 ** 9) ** 2) ** 2
;也就是
[(29)2]2=29×2×2=236,
236个字节等于64MB
是一个编译成.exe
的C++
程序A+B problem
的60+倍!