python函数装饰器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python函数装饰器相关的知识,希望对你有一定的参考价值。

学习装饰器前提需要了解高阶函数,函数嵌套,函数闭包

python函数装饰器,顾名思义就是装饰函数,为函数添加新功能的的一种方式。

为什么要使用装饰器呢?

因为函数在运行时,如果不使用装饰器对函数进行功能添加,需要修改函数源代码,这样修改无疑会增加程序的冗余和复杂性,也不便于程序员对其进行修改。使用装饰器,可以在不改变函数源代码和调用方式的前提下,使用语法糖@装饰器,对函数功能进行添加。

装饰器本质上就是一个函数。

我们使用一个简单的例子来实现:

import time
#这是一个装饰器函数名为timer
def timer(func):#将原函数(func)以参数形式传入装饰器函数
    def wapper():#定义装饰函数wapper
        start_time=time.time()
        func()#调用原函数
        stop_time=time.time()
        print("程序的运行时间为%s"%(stop_time-start_time))
    return wapper#返回wapper函数给timer

@timer#定义index=timer(index)
def index():
    time.sleep(2)
    print("这是一个测试程序")

index()

以上是一个无参数装饰器,有时候我们需要用到带参数的装饰器,比如登录验证,

import time
#这是一个装饰器函数名为timer
def timer1(auth_type):
    print(auth_type)#打印auth_type值,方便自己查看程序流程
    def timer(func):#将原函数(func)以参数形式传入装饰器函数
        def wapper():#定义装饰函数wapper
            if auth_type=="file":
                start_time=time.time()
                func()#调用原函数
                stop_time=time.time()
                print("程序的运行时间为%s"%(stop_time-start_time))
            else:
                print("不知道你输入的是什么")
        return wapper#返回wapper函数给timer
    return timer#返回timer给timer1

@timer1(auth_type="file")#定义index=timer(index(auth_type))
def index():
    time.sleep(2)
    print("这是一个测试程序")

index()

 在使用装饰器过程中我们发现原函数的源信息不见了,当我们需要原函数的返回值,在原函数处是无法返回也没有的,这就需要我们重新理解装饰器语法糖的作用,不难发现,原函数已经变为装饰器中的函数wapper

以下实例根据以上代码试验:

通过使用,我们发现原函数的元信息显示结果为none

@timer1(auth_type="file")#定义index=timer(index(auth_type))
def index():
    """这是原函数信息"""
    time.sleep(2)
    print("这是一个测试程序")
print(index.__doc__)

#结果为none

经过试验,可以验证,被修饰函数的元信息在装饰器中添加会有效打印

 def wapper():#定义装饰函数wapper
            """装饰器中的元信息"""

针对这种情况,我们可以使用functools.wraps  wraps本身也是一个装饰器,他能把原函数的的元信息拷贝到装饰器中,使装饰器函数有原函数一样的源信息

from functools import wraps#调用工具
def timer1(auth_type):
    print(auth_type)#打印auth_type值,方便自己查看程序流程
    def timer(func):#将原函数(func)以参数形式传入装饰器函数
        @wraps(func)将该工具装饰器插入到装饰器函数正上方
        def wapper():#定义装饰函数wapper

我们也可以定义多个装饰器给函数使用,需要注意的是装饰器的调用顺序

@a

@b

@c

def f()

这种装饰就等效于f=a(b(c(f)))

以上是关于python函数装饰器的主要内容,如果未能解决你的问题,请参考以下文章

python 装饰器

[TimLinux] Python 装饰器

python装饰器

python函数装饰器

Python装饰器

python装饰器