python 装饰器、给装饰器传参

本文深入解析Python装饰器的概念,包括其工作原理、如何定义和使用装饰器,以及装饰器在函数参数验证、性能调试和功能增强等方面的应用。同时,通过具体代码示例,展示装饰器在实际编程中的强大功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、装饰器

专业解释简介:python用特殊的语法来表示装饰器(decorator),这些装饰器可以用来修饰函数。对于受到封装的原函数来说,装饰器能够在那个函数执行之前以及执行完毕之后,分别运行一些附加代码。这使得开发者可以在装饰器里面访问访问并修改原函数的参数及及返回值,以实现约束语义、调试程序、注册函数等目标。

个人理解:对原有函数进行二次封装,实现原函数没有的附加功能

使用:定义好装饰器函数,使用@符号来修饰函数,作用相当于在装饰器内部调用装饰的那个函数

2、代码

  • 给装饰器不传递参数
from functools import wraps


def trace(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print('%s(%r, %r) -> %r' % (func.__name__, args, kwargs, result)) # 重点:%r为万能格式化字符串
        return result

    return wrapper


@trace
def fibonacci(n):
    if n in (0, 1):
        return n

    return fibonacci(n - 2) + fibonacci(n - 1)


if __name__ == '__main__':
    fibonacci(3)
    print(fibonacci)

输出结果:

fibonacci((1,), {}) -> 1
fibonacci((0,), {}) -> 0
fibonacci((1,), {}) -> 1
fibonacci((2,), {}) -> 1
fibonacci((3,), {}) -> 2
<function fibonacci at 0x00000000025777B8>

注意:如果不使用@wraps,会使被装饰的函数对于内置的help函数失效,使用print函数打印被装饰的函数,显示的函数名字也会不一样,还会导致其余一些难以排查的问题。因此,我们需要使用wraps来保证装饰后的函数具备正确的行为。

以下是没有使用wraps函数做处理显示的结果:

print(fibonacci)
>>> <function trace.<locals>.wrapper at 0x00000000023A77B8>

help(fibonacci)
>>> Help on function wrapper in module __main__:

    wrapper(*args, **kwargs)
        # @wraps(func)
  • 给装饰器传递参数
from functools import wraps


def verify_data(name=""):
    # 对参数做外层校验
    print(name)

    def get_result(func):
        @wraps(func)
        def re_wraps(*args, **kwargs):
            result = func(*args, **kwargs)
            print('%s(%r, %r) -> %r' % (func.__name__, args, kwargs, result))

            return result

        return re_wraps

    return get_result


@verify_data('add')
def add():
    return 1 + 1


print(add())

 3、在这里顺便说一下闭包

装饰器就是由闭包实现的,闭包必须满足的三个条件

  1. 必须是一个嵌套的函数。
  2. 闭包必须返回嵌套函数。
  3. 嵌套函数必须引用一个外部的非全局的局部自由变量。

闭包函数的优点:

  • 避免使用全局变量
  • 可以提供部分数据的隐藏
  • 可以提供更优雅的面向对象实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值