DAY31 函数专题2:装饰器

前言:在上一个章节中我们主要讨论了函数的基本定义方式和基本的用法,在本节中我们将引入一个新的概念装饰器。装饰器是函数的"外包装",装饰器是一个可以给函数"穿衣服"的特殊函数,不改变原函数代码就能增加新功能。

一、选用装饰器的原因

原因一:使用装饰器可以提升代码复用,例如我有多个函数需要测量执行时间,我可以直接将装饰器应用在这些函数上,而不用在每个函数上进行重复代码的书写。

原因二:保证函数的逻辑清晰,使用装饰器可以使得一个函数只承担单一的责任。

原因三:扩展他人写好的函数,通过装饰器可以直接添加额外功能,而不需要去对应的库中进行相关的修改。

二、应用示例

编写一个装饰器logger,在函数执行前后打印日志信息(如函数名、参数、返回值)。

python 复制代码
def logger(func):
    def wrapper(*args, **kwargs):  # 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)  # 调用 multiply 函数,观察日志输出

其中

@logger

def multiply(a, b):

return a * b

multiply(2, 3)

--------------------------------------------------------等价于----------------------------------------------------------------

def multiply(a, b):

return a * b

multiply = logger(multiply)

值得注意的是

return wrapper(返回函数本身,可多次使用的工具)、return wrapper()(立即执行函数,一个结果值)。

举个例子:对于return wrapper:

python 复制代码
def create_calculator(operation):
    if operation == "add":
        def add_numbers(a, b):
            return a + b
        return add_numbers  # 返回加法计算器
    
    elif operation == "multiply":
        def multiply_numbers(a, b):
            return a * b
        return multiply_numbers  # 返回乘法计算器

# 得到计算器
my_adder = create_calculator("add")
my_multiplier = create_calculator("multiply")

# 可以多次使用
print(my_adder(2, 3))      # 5
print(my_adder(10, 20))    # 30
print(my_multiplier(4, 5))  # 20

对于 return wrapper():

python 复制代码
def calculate_once():
    def add_numbers(a, b):
        return a + b
    
    return add_numbers(2, 3)  # ❌ 立即计算 2+3

# 只能得到一个结果
result = calculate_once()
print(result)  # 5

# 不能计算其他数
# 这个函数只能算 2+3

一个参数设定时的典型错误:

关键规则总结

  1. 顺序:位置参数必须在前,关键字参数在后

  2. 一旦用关键字参数,后面的所有参数必须都用关键字参数

  3. 可以混用,但必须保持"位置→关键字"的顺序

  4. 关键字参数可以打乱顺序,因为Python按名称分配

@浙大疏锦行

相关推荐
天天被压力7 分钟前
【A股分钟级高频数据完全手册 #10】股票实时行情数据接口Python:公开源实时交易取数
java·人工智能·python
特立独行的猫A10 小时前
我给女儿写了个打字练习:一边敲键盘,一边把小学英语单词记牢
java·后端·python
cpolar技术支持10 小时前
「我这边连不上你那个服务」—— 用清单驱动的 TCP 连通性只读看板,cpolar 让远端同事自己取证
python·内网穿透·tcp·cpolar·网络诊断
云和数据.ChenGuang11 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
天诰12 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
benchmark_cc12 小时前
用 QuantDash 读取美股行情:AAPL.US 的运行前检查、排错顺序与数据校验清单
python·数据分析·pandas·量化交易·股票数据·quantdash
羲云网络16 小时前
GPT Image 2.6 接入指南:Flare、Sunburst 怎么选,编辑失败如何排查
人工智能·python·aigc·图像生成·acedatacloud
橙橙笔记19 小时前
具身智能的学习 - 完成一个机械臂 第1节
python·学习·机械臂·具身智能
小小张说故事19 小时前
Python 的 class 语句到底执行了什么?拆开 __prepare__、metaclass.__new__ 和那个被讲反的 __set_name__ 顺序
python
天天被压力21 小时前
【A股分钟级高频数据完全手册 #07】北交所历史分钟K线接口:京市Pro版分时批量
java·人工智能·python