【Python】四、装饰器

    在一些反复使用的语句或函数的应用场景时,修改的封闭性不能很好地保证,或者不够优雅,装饰器解决了这一问题

    例如,当我们想知道程序的运行时间时,在开始运行前获取一个时间戳,运行结束时获取一个时间戳,两者做差,能够得出程序的运行时间,需要每次调用函数时,在首尾都要添加获取时间戳函数,之后做差,一旦修改需求,就会很麻烦,我们可以使用装饰器

装饰器的实质与闭包类似,其中体现了函数是一个对象,可以传入作为参数

import time

def decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print("running time:" + str(end - start))
    return wrapper

def func(n):
    sum = 0
    for i in range(n):
        sum += i

f = decorator(func)
f(10000)

装饰器的python语法糖,让这样的格式变得方便,上下两者等价

import time


def decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print("running time:" + str(end - start))
    return wrapper

@decorator
def func(n):
    sum = 0
    for i in range(n):
        sum += i

func(100000)

装饰器语法

def decorator(func):
    def wrapper(*args,**kwargs):
        ...
        func(*args,**kwargs)
    return wrapper
  • wrapper封装起来

  • 可以用@+装饰器名称调用,不影响原函数的调用

装饰器的问题

实际上,添加装饰器的函数,已经不是原来的函数了,在过程中改变,可以通过运行func.__name__ 看出,结果为wrapper

可以通过调用functools中的wraps可以保留原函数的名字和文档

import time
from functools import wraps


def decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        func(*args, **kwargs)
        end = time.time()
        print("running time:" + str(end - start))
    return wrapper

@decorator
def func(n):
    sum = 0
    for i in range(n):
        sum += i

func(100000)
print(func.__name__)

此时__name__结果为func

posted @ 2021-09-25 10:13  灰灰不吃鱼  阅读(33)  评论(0编辑  收藏  举报