01_装饰器

装饰器是一种在不修改函数源代码的情况下增加功能的Python语法,常用于日志、性能测试、事务处理等。它们通过闭包实现,可以不改变调用方式增强函数行为。文章介绍了不带参数和带参数的装饰器用法,并展示了如何使用`functools.wraps`进行优化,确保被装饰函数的元信息正确。最后,给出了计算序列和时间消耗的装饰器示例。
摘要由CSDN通过智能技术生成

装饰器的概念以及优点

装饰器: 装饰器,装饰的对象是函数或者方法。各种装饰器的作用都是一样的:改变被装饰函数或者方法的功能,性质。
装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。装饰器用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

装饰器特点

  1. 不改变被装饰的函数的源代码的情况下添加函数的功能
  2. 不改变被装饰的函数的调用方式

装饰器优点

  1. 程序可读性高
  2. 代码复用性高
  3. 你的编程思路更加宽广

为啥使用装饰器

我们有一个函数my_fun(mesage),如下:

def my_fun(message):
    print("Hello {message}")

如果我们要在这个my_fun(message)中,print代码前增加一个输出welcome的命令,我们可以通过增加print(“welcome”)来进行操作,如下:

def my_fun(message):
    print("welcome")
    print("Hello {message}")

但是如果我们需要增加print(“welcome”)的函数特别多,且print(“welcome”)又多次变更其他提示信息,那我们还要一个一个的给函数增加或者修改吗??那样是不是特别耗费时间,且修改的地方较多,装饰器可以解决这个问题。

不带参数的装饰器

装饰器的使用

调用装饰器的方法有两种,第一种最常用,如下:

#不带参数的装饰器

#自定义装饰器
def welcome(fn):
    def wrapper(*args, **kargs):
        print("welcome")
        result = fn(*args, **kargs)
        return result
    return wrapper    


@welcome
def my_fun(message):
    print(f"Hello {message}")

# 装饰器的调用有两种方法:
# 第一种,第一步-先在需要调用的函数前加@welcome
# 第二步:然后调用需要调用的函数即可
my_fun('zhangsan')
print(my_fun) # <function welcome.<locals>.wrapper at 0x000001F1D2215488>

第二种,如下:

#不带参数的装饰器

#自定义装饰器
def welcome(fn):
    def wrapper(*args, **kargs):
        print("welcome")
        result = fn(*args, **kargs)
        return result
    return wrapper    

def my_fun(message):
    print(f"Hello {message}")

f1 = welcome(my_fun) # 获得内部函数wrapper函数
res = f1("jack") # 调用wrapper函数

装饰器的优化

在这里插入图片描述my_fun()–调用的是my_fun函数,但是在打印函数的时候,确显示为wrapper函数,这个怎么处理呢?使用wraps装饰器即可解决,如下:

from functools import wraps
#自定义装饰器
def welcome(fn):
    @wraps(fn)
    def wrapper(*args, **kargs):
        print("welcome")
        result = fn(*args, **kargs)
        return result
    return wrapper    


@welcome
def my_fun(message):
    print(f"Hello {message}")

# 装饰器的调用有两种方法:
# 第一种,第一步-先在需要调用的函数前加@welcome
# 第二步:然后调用需要调用的函数即可
my_fun('zhangsan')
print(my_fun) # <function my_fun at 0x00000209CA435488>

方法如下:
第一步:先导入wraps方法-from functools import wraps
第二步:在自定义装饰器函数中增加@wraps(fn),这个fn的参数是不需要要写的。

带参数的装饰器

# 带参数的装饰器
from functools import wraps

def welcome(name):
    
    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kargs):
            print(f"welcome {name}")
            result = fn(*args, **kargs)
            return result
        return wrapper
    return decorator

@welcome('Tom') #装饰器会先执行welcom("Tom")返回一个装饰器函数,然后在执行@
def my_fun(message):
    print(f"hello {message}")

my_fun("JACK")

例子

使用装饰器,分别计算1+…+100和1+…1000的花费时间,请用装饰器实现

from functools import wraps
import time

def getTimer(fn):
    @wraps(fn)
    def wrapper(*args, **kargs):
        start_time = time.time()
        result = fn(*args, **kargs)
        end_time = time.time()
        print(f"共花费{end_time-start_time}秒")
        return result

    return wrapper

@getTimer
def add(num):
    total = 0
    for i in range(num):
        total += i
    return total

print(add(101))
print(add(10000001))

# 共花费0.0秒
# 5050
# 共花费2.4837872982025146秒
# 50000005000000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值