当前位置:首页>python>从零开始学python-装饰器

从零开始学python-装饰器

  • 2026-08-26 04:42:47
从零开始学python-装饰器

Hi~新朋友,记得点上面蓝字(网虫root)关注哟~

前言:

   装饰器允许在不修改原函数代码的情况下,动态地增强函数的功能。装饰器本质上是一个接收函数作为参数并返回新函数的函数。

1. 装饰器的基本语法

def decorator_function(original_function):    def wrapper(*args, **kwargs):        # 在调用原函数前添加额外功能        result = original_function(*args, **kwargs)        # 在调用原函数后添加额外功能        return result    return wrapper@decorator_functiondef target_function():    pass

💡语法要点:

  • 装饰器函数:接收一个函数作为参数

  • 包装函数(wrapper):在装饰器函数内部定义,用于包裹原函数

  • @语法:用于应用装饰器,等同于target_function = decorator_function(target_function)

2. 简单的装饰器:在函数执行前后各打印一句话

🌅示例:一个简单的日志装饰器

def my_decorator(func):    """这是一个最简单的装饰器"""    print("1. 装饰器 my_decorator 被调用了,它接收到的函数是:", func.__name__)    def wrapper():        print("3. 正在执行 wrapper 函数,这是在调用原函数之前")        func()                     # 调用原函数        print("5. 这是调用原函数之后,wrapper 函数执行完毕")    print("2. 装饰器准备返回 wrapper 函数")    return wrapper# 使用 @ 语法应用装饰器@my_decoratordef say_hi():    print("4. 原函数 say_hi 正在执行")# 调用被装饰后的函数print("--- 开始调用 say_hi() ---")say_hi()print("--- 调用结束 ---")

🏁输出结果:

1. 装饰器 my_decorator 被调用了,它接收到的函数是: say_hi2. 装饰器准备返回 wrapper 函数--- 开始调用 say_hi() ---3. 正在执行 wrapper 函数,这是在调用原函数之前4. 原函数 say_hi 正在执行5. 这是调用原函数之后,wrapper 函数执行完毕--- 调用结束 ---

2. 装饰器执行过程

上面的输出揭示了装饰器的完整执行过程,以下是流程图:

🎯关键点总结:

  • 装饰器本身在函数定义时立即执行,不是在调用时执行。@my_decorator 背后的 say_hi = my_decorator(say_hi) 在定义阶段就完成了。

  • 被装饰后的函数名指向了新的 wrapper 函数。之后每次调用 say_hi(),实际执行的都是 wrapper 内部的代码。

  • wrapper 内部可以在调用原函数前后添加任意代码,实现了“增强”效果。

3. 如果原函数需要参数怎么办?

上面的例子中 say_hi 没有参数,但实际函数往往需要参数。为了让装饰器能处理任意函数,需要在 wrapper 中使用 *args 和 **kwargs 来接收所有参数,并传递给原函数。

🧭示例:装饰带参数的函数

def my_decorator(func):    def wrapper(*args, **kwargs):          # wrapper 接收任意参数        print("调用前:做一些准备工作")        result = func(*args, **kwargs)     # 将参数原样传递给原函数        print("调用后:做一些清理工作")        return result                       # 返回原函数的返回值    return wrapper@my_decoratordef greet(name, greeting="Hello"):    print(f"{greeting}, {name}!")    return "返回值:" + greeting# 调用output = greet("小明", greeting="你好")print("函数的返回值是:", output)

📌输出结果:

调用前:做一些准备工作你好, 小明!调用后:做一些清理工作函数的返回值是: 返回值:你好

这里 *args 和 **kwargs 收集了所有位置参数和关键字参数,使得装饰器可以应用于任何函数,无论它有多少参数。

4. 常见疑问

问:为什么装饰器里的 wrapper 要叫这个名字? 答:只是一个习惯名称,你可以叫任何名字,但通常用 wrapper 表示它是包装函数。

问:多个装饰器一起用会怎样? 答:它们会像剥洋葱一样一层层包装,从下往上应用。例如 @A 在上,@B 在下,相当于 func = A(B(func))。调用时先执行 A 的“前”代码,再执行 B 的“前”代码,然后原函数,然后 B 的“后”代码,最后 A 的“后”代码。对于新手,建议先掌握单个装饰器。

5. 一个完整的、可自己运行的简单示例

# 定义装饰器def simple_logger(func):    print(f"【装饰器】正在装饰函数:{func.__name__}")    def inner():        print("    [inner] 进入 inner 函数")        func()        print("    [inner] 退出 inner 函数")    print("这是第2步就是马上执行下面的return inner(也就是马上执行inner装饰器函数)")    return inner# 使用装饰器@simple_loggerdef test():    print("        [test] 原函数执行中")# 调用print("=" * 30)test()print("=" * 30)

运行这个代码,你会看到清晰的执行顺序。建议你把这段代码复制到自己的环境中运行,观察输出,这样理解会更深刻。

【微语】别想太多,好好生活,也许日子过着过着就会有答案,努力走着走着就会有温柔的着落。

网虫root

期待你的

分享

点赞

在看

最新文章

随机文章