不知道看到这篇文章的各位有没有实际面试经历,本王作为一个经历过很多次面试的应聘者身份,被问到修饰器的次数很多,接下来就来看看修饰器的一些高级知识。
为什么是高级知识呢?因为你去搜索引擎搜索 “python 修饰器” 的时候,都是千篇一律的基础 ? ,一点高级的内容都没有 ? ,一点使用经验的分享都没有 ? ,那我就想写一篇不一样的以正视听 ? 。
开篇明义,修饰器的核心思想就是在——目标对象外面加一层壳,目标对象的输入先要经过修饰器,目标对象的输出后要流经修饰器。
准备了一个 ? 群,可加 537131912
Python 内部是怎么实现修饰器的
源代码:
def decorator(func):
print('>>>>>>>>>>>>>>>>>>>>')
def inner():
print('被修饰了')
return func()
return inner
@decorator
def print_ok():
print('ok')
print_ok()
复制代码
上述代码输出如下:
>>>>>>>>>>>>>>>>>>>>
被修饰了
ok
复制代码
那么 Python 解释器做了什么使得可以实现上述的输出?原理就是执行到 @decorator
这一行的时候,执行了这样的代码 print_ok = decorator(print_ok)
。所以,这个时候你打印 print(type(print_ok ))
,就会看到如下的结果:
源代码:
def decorator(func):
print('>>>>>>>>>>>>>>>>>>>>')
def inner():
print('被修饰了')
return func()
return inner
@decorator
def print_ok():
print('ok')
print(print_ok)
复制代码
上述代码的输出:
>>>>>>>>>>>>>>>>>>>>
<function decorator.<locals>.inner at 0x000001DF9936AE50>
复制代码
如果不用修饰器修饰的话 ?
def print_ok():
print('ok')
print(print_ok)
复制代码
上述代码的输出:
<function print_ok at 0x0000018599DAADC0>
复制代码
可以看到使用修饰器 @decorator
修饰 print_ok
之后, print_ok
就不是 print_ok
自己了,而是变成了的 decorator
的返回值对应的内容,来了一个偷天换日,你以为 print_ok
还是 ?
def print_ok():
print('ok')
复制代码
实际上 print_ok
指向的是 ?
def inner():
print('被修饰了')
return func()
复制代码
我们也可以使用下面的代码来实现一个不使用 @
符号的修饰器。
源代码:
def decorator(func):
print('>>>>>>>>>>>>>>>>>>>>')
def inner():
print('被修饰了')
return func()
return inner
def print_ok():
print('ok')
print_ok = decorator(print_ok)
print_ok()
复制代码
上述代码输出如下:
>>>>>>>>>>>>>>>>>>>>
被修饰了
ok
复制代码
@
操作符用于修饰器的时候,@
符号被称为语法糖,什么是语法糖?就是可以不用也能实现同样的功能,但是用了语法糖可以更爽,表现在:写更少的代码,让代码更漂亮更优雅。所以我们要使用修饰器不一定要使用@
符号,可以通过print_ok = decorator(print_ok)
实现。
什么时候需要使用修饰器
其实使用修饰器的时机就两个:
- 不能动源码
- 不想碰屎山
总结就是不想动原来的,想在原基础上重写一些新的。
不能动源码
不能动源码很好理解,不用解释吧
我们用一个第三库都是 import 它,然后想在他基础上增加点东西都是加修饰器,为什么要加修饰器,因为这不会破坏它本身,加修饰器本质就是套壳。
不想碰屎山
当你回看自己几个月前的代码的时候,你发现已经不认识这些代码的逻辑了,不敢修改了,怕牵一发动全身,或者说不想花时间去读懂这些曾经的代码了,这个时候就可以使用修饰器,(可以使用不意味着肯定可以使用,有些场景还是需要自己去硬着头皮去 Review 代码的 ),这个时候修饰器充当的就是补丁的角色。
上面说的情况也可以套用在同事的代码上 ? 。
什么?你不知道什么是屎山 ⛰️ ?看这里 ? 为什么祖传代码被称为「屎山」?
内置修饰器
有四大内置修饰器,分别是
-
classmethod
-
staticmethod
-
property
-
warps
Python
的内置修饰器有一大堆,上面 4 个覆盖了内置修饰器的 99% 的使用率。
TODO
自定义修饰器
主要有 4 种情况:
-
不带参数的函数修饰器
-
带参数的函数修饰器
-
不带参数的类修饰器
-
带参数的类修饰器
看起来很多复杂,但是理解了 print_ok = decorator(print_ok)
这句代码之后,理解上面四种情况就非常的 easy 了呀 ?
上面四种情况怎么写、怎么用就去搜索引擎查一下吧!关键词都给你了。