Python修饰器是难点?光知道语法是不够的,这里还有一些进阶知识

不知道看到这篇文章的各位有没有实际面试经历,本王作为一个经历过很多次面试的应聘者身份,被问到修饰器的次数很多,接下来就来看看修饰器的一些高级知识。

为什么是高级知识呢?因为你去搜索引擎搜索 “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 了呀 ?

上面四种情况怎么写、怎么用就去搜索引擎查一下吧!关键词都给你了。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享