Python基础教程

007_Python装饰器

Python装饰器

Python装饰器的理解

装饰器就是包装器,是包装和装修的意思。比如,有一个普通函数,现在需要在不改变这个函数代码的情况下,给它添加新功能。

函数嵌套可以实现装饰器功能,就是把普通函数放到另一个函数内部,在外层函数中添加新功能,达到包装的效果。

Python中一切皆对象,int和list是对象,函数也是对象,对象名称就是函数名,可以作为其他函数的参数。内层函数名也可以作为外层函数的返回值。

# 普通功能函数
def myfun():
    print("hello,myfun")

# 直接调用普通函数
myfun()
print("-----------------------------")

# 装饰器函数
def deco(afun):
    def infun():
        print("before do")
        afun()
        print("after do")
    return infun            # 将包装后的内层函数作为返回值,供外界调用

# 将普通函数名传入装饰器
test_deco=deco(myfun)
# 调用装饰器函数
test_deco()

运行结果

C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
hello,myfun
-----------------------------
before do
hello,myfun
after do

Process finished with exit code 0

Python装饰器与@语法以及wraps工具

Python提供@语法,使装饰器通过注解来实现。这样在形式上感觉原函数(普通函数)在使用上似乎没有变化。这样有个好处就是,以前使用普通函数的地方不需要改动就能全部添加装饰器中的内容。

Python内置的functools.wraps工具可以保证原函数(普通函数)的名字和注释文档经过装饰器后能正常显示(而不是显示装饰器自己的内容)。这样才能做到既包装,又不留痕迹。

from functools import wraps
# 装饰器函数
def deco(afun):
    @wraps(afun)
    def infun():
        print("before do")
        afun()
        print("after do")
    return infun            # 将包装后的内层函数作为返回值,供外界调用

@deco
def myfun():
    print("hello,myfun")

# 普通函数变成了装饰器函数了,再也不普通
myfun()

运行结果

C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
before do
hello,myfun
after do

Process finished with exit code 0

Python装饰器带参数

为了使装饰器能够包装各种函数(是否带参数,参数个数可多可少),我们需要在装饰器中使用函数可变参数特性。

from functools import wraps
# 装饰器函数
def deco(afun):
    @wraps(afun)
    def infun(*args,**kw):
        print("before do")
        for item in args:
            print(item)     # 可变参数
        res=afun(*args,**kw)
        print("after do")
        return res
    return infun            # 将包装后的内层函数作为返回值,供外界调用

@deco
def myfun(x,y):
    print("hello,myfun:",x+y)

# 普通函数变成了装饰器函数了,再也不普通
myfun(1,2)

运行结果

C:UsershccmaAnaconda3python.exe E:/wkp01/p00/test01/py001/t09.py
before do
1
2
hello,myfun: 3
after do

Process finished with exit code 0

Python装饰器可以用类实现

在Python装饰器既可以用函数实现,也可以用对象(类)实现,这里不作展开讲解。

装饰器模式是一种设计模式,一种编程思想。

这篇文章对您有用吗?

我们要如何帮助您?