装饰器的写法

本文深入探讨了Python装饰器的概念及其在日志记录、性能测试等场景中的应用。装饰器允许在不修改原有函数代码的情况下,添加额外功能,提升代码的优雅性和可读性。通过实例展示了普通装饰器和带参数装饰器的实现,包括如何在装饰器中传入参数以适应不同场景。装饰器是Python编程中一种强大的代码组织工具,能够有效提高代码的复用性和灵活性。
摘要由CSDN通过智能技术生成

装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

装饰器的使用方法很固定

  • 先定义一个装饰器(帽子)
  • 再定义你的业务函数或者类(人)
  • 最后把这装饰器(帽子)扣在这个函数(人)头上

就像下面这样子

# 定义装饰器
def decorator(func):
    def wrapper(*args, **kw):
        return func()
    return wrapper

# 定义业务函数并进行装饰
@decorator
def function():
    print("hello, decorator")

实际上,装饰器并不是编码必须性,意思就是说,你不使用装饰器完全可以,它的出现,应该是使我们的代码

  • 更加优雅,代码结构更加清晰
  • 将实现特定的功能代码封装成装饰器,提高代码复用率,增强代码可读性

1. 第一种:普通装饰器

首先咱来写一个最普通的装饰器,它实现的功能是:

  • 在函数执行前,先记录一行日志
  • 在函数执行完,再记录一行日志
# 这是装饰器函数,参数 func 是被装饰的函数
def logger(func):
    def wrapper(*args, **kw):
        print('我准备开始执行:{} 函数了:'.format(func.__name__))

        # 真正执行的是这行。
        func(*args, **kw)

        print('主人,我执行完啦。')
    return wrapper

假如,我的业务函数是,计算两个数之和。写好后,直接给它带上帽子。

@logger
def add(x, y):
    print('{} + {} = {}'.format(x, y, x+y))

然后执行一下 add 函数。

add(200, 50)

来看看输出了什么?

我准备开始执行:add 函数了:
200 + 50 = 250
我执行完啦。

2. 第二种:带参数的函数装饰器

装饰器本身是一个函数,做为一个函数,如果不能传参,那这个函数的功能就会很受限,只能执行固定的逻辑。这意味着,如果装饰器的逻辑代码的执行需要根据不同场景进行调整,若不能传参的话,我们就要写两个装饰器,这显然是不合理的。

比如我们要实现一个可以定时发送邮件的任务(一分钟发送一封),定时进行时间同步的任务(一天同步一次),就可以自己实现一个 periodic_task (定时任务)的装饰器,这个装饰器可以接收一个时间间隔的参数,间隔多长时间执行一次任务。

由于这个功能略显复杂,此处就不贴代码了

那我们来自己创造一个伪场景,可以在装饰器里传入一个参数,指明国籍,并在函数执行前,用自己国家的母语打一个招呼。

# 小明,中国人
@say_hello("china")
def xiaoming():
    pass

# jack,美国人
@say_hello("america")
def jack():
    pass

那我们如果实现这个装饰器,让其可以实现 传参 呢?
会比较复杂,需要两层嵌套。

def say_hello(contry):
    def wrapper(func):
        def deco(*args, **kwargs):
            if contry == "china":
                print("你好!")
            elif contry == "america":
                print('hello.')
            else:
                return

            # 真正执行函数的地方
            func(*args, **kwargs)
        return deco
    return wrapper

来执行一下

xiaoming()
print("------------")
jack()

看下结果

你好!
------------
hello.

好了,今天就先到这里,下次小张学了新的再继续分享!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值