DAY27装饰器@XXX
2026/7/22 13:00:53 网站建设 项目流程

浙大疏锦行

今日内容核心:装饰器(Decorator)

1. 装饰器是什么?

  • 本质:一个函数,它接收另一个函数作为参数,返回一个新函数(通常叫wrapper),在不修改原函数代码的前提下,为原函数增加额外功能(如计时、日志、权限校验等)。
  • 目的:遵循DRY 原则(Don’t Repeat Yourself),将重复的辅助逻辑(如计时)抽离出来,让核心函数更干净、可读性更强。

2. 装饰器的基本结构(无参数、无返回值)

defdisplay_time(func):defwrapper():# 前置操作start=time.time()func()# 调用原函数# 后置操作print(time.time()-start)returnwrapper# 返回新函数,而非执行它
  • 使用@display_time语法糖,等价于prime_nums = display_time(prime_nums)
  • 调用prime_nums()时,实际执行的是wrapper()

3. 带参数的被装饰函数如何处理?

  • wrapper(*args, **kwargs)接收任意位置参数和关键字参数,然后原样传给func(*args, **kwargs)
  • 这样装饰器就可以复用于任何参数形式的函数。

4. 带返回值的被装饰函数如何处理?

  • wrapper中需要result = func(...)return result,保证原函数的返回值能传递出去。

5. 执行顺序(单步调试会看到)

  1. 定义display_time
  2. 定义prime_nums,并立即应用@display_time→ 执行display_time(prime_nums),得到wrapper
  3. 此时prime_nums这个名字被重新绑定到wrapper
  4. 调用prime_nums()→ 进入wrapper→ 执行计时 → 调用原始的prime_nums(即func)→ 打印质数 → 输出耗时

你笔记中range(2, num)的运用

在判断素数is_prime(num)中:

foriinrange(2,num):ifnum%i==0:returnFalse
  • range(2, num)生成从 2 到num-1的整数序列,用于测试所有可能的除数。
  • 如果num能被其中任何一个数整除,则不是素数;否则是素数。
  • 注意:num=2时,range(2,2)为空,循环不执行,直接返回True(所以笔记中单独处理了num==2)。

装饰器与普通函数计时对比

  • 普通写法:计时代码混在prime_nums内部,干扰核心逻辑。
  • 装饰器写法:计时逻辑独立成display_timeprime_nums只关心找质数,代码更清晰,且计时功能可复用于其他函数。

今日总结一句话

装饰器是“函数的函数”,通过@语法糖将原函数包装,在不改动原函数内部代码的情况下为其增加额外能力。理解其本质是func = decorator(func)的替换过程,并掌握*args, **kwargs传递参数以及return返回值,就能应对绝大多数场景。

今日作业:

def logger(func):
def wrapper(*args, **kwargs):
print(f"开始执行函数 {func.name},参数: {args}, {kwargs}“)
result = func(*args, **kwargs)
print(f"函数 {func.name} 执行完毕,返回值: {result}”)
return result
return wrapper

@logger
def multiply(a, b):
return a * b

multiply(2, 3)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询