python中的装饰器

做~自己de王妃 提交于 2019-12-11 12:36:50

python中的装饰器

装饰器简单来说就是一个函数,具有附加其他函数功能的能力
python是面向对象的编程,所以在python中一切皆为对象,那么函数也是对象。

既然是对象就可以进行赋值操作

'''赋值操作'''
def func():
    print("hello")

if __name__=="__main__":
    text = func
    text()

运行结果

hello

这里可以看出text()实现了自定义函数一样的功能

也可以作为参数传递给其他函数

'''作为参数操作'''
def func():
    print("hello")
def text(func):
    func()

if __name__=="__main__":
    text(func)

运行结果

hello

还可以在函数内部定义函数

'''内置函数'''
def text():
    def func():
        print("hello")
    return func

if __name__=="__main__":
    text1 = text()
    text1()

运行结果

hello

综上,我们可以细化一下装饰器的工作流程
1.定义一个函数(装饰器),且以一个函数作为参数(形参函数)
2.在这个定义函数(装饰器)内部内置一个函数
3.在内置函数中实现一些功能,并调用传递进来的函数(实参函数)
4.将内部函数作为返回值返回

def func(x):
    def inner():
        print("hello")
        x()
    return inner
@func
def f1():
    print("world")
@func
def f2():
    print("python")

if __name__=="__main__":
    f1()
    print("")
    f2()

运行结果

hello
world

hello
python

从运行结果可以看到,我们再不改变f1()和f2()函数的情况下在函数中附加了运行“hello”的功能

当两个或以上装饰器作用在一个函数上时

def func1(x):
    def inner():
        x()
        print("python")
    return inner

def func2(y):
    def inner():
        y()
        print("world")
    return inner

@func1
@func2
def func():
    print("hello")

if __name__=="__main__":
    func()

运行结果

hello
world
python

类似先进后出原则,也可以看成打包装,最后调用的装饰器为最里层包装,直到所有包装均完成

深入讨论

1.被装饰的函数带返回值

实际上我们最终调用的被装饰实参函数已经变为我们的内部函数
被装饰的函数(实参函数)的返回值只需要通过装饰器内部定义的函数返回值返回即可。

在没有返回值的情况下

def func(x):
    def inner():
        print("hello")
    return inner

@func
def f():
    print("world")
    return
if __name__=="__main__":
    f()

运行结果

hello

在inner函数中对非f()进行了调用,但是没有接受返回值,也没有进行返回,那么默认None了

加上返回值

def func(x):
    def inner():
        print("hello")
        return x()
    return inner

@func
def f():
    print("world")
    return
if __name__=="__main__":
    f()

运行结果

hello
world

2.被装饰的函数带参数

如果原函数有参数,那闭包函数必须保持参数个数一致,并且将参数传递给原方法
也就是说内置函数需要与实参函数保持一致的参数

def func(n):
    def inner(x, y):
        sum = x + y
        return n(sum)
    return inner

@func
def f(p):
    print("The sum is : ", p)
    return

if __name__=="__main__":
    f(2, 3)

运行结果

The sum is :  5

3.装饰器带参数

简单理解,带参数的装饰器就是在原闭包的基础上又加了一层闭包

好处就是可以在运行时,针对不同的参数做不同的应用功能处理。

def func_args(pre="python"):
    def func(x):
        def inner():
            print("hello", pre)
            return x()
        return inner
    return func

@func_args('python')
def f():
    print("world")
    return
if __name__=="__main__":
    f()

带有参数的装饰器能够起到在运行时,有不同的功能
先执行func_args(‘python’),返回func函数的引用
使用@func()对f()进行装饰
运行结果

hello python
world

参考链接

https://www.jb51.net/article/158814.htm

https://blog.csdn.net/weixin_45514627/article/details/103212346

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!