Files

84 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第 2-6 课课堂练习:装饰器
#
# 请先阅读讲义并运行完整示例,再按照题目顺序完成。
# 装饰器必须调用原函数并保留原函数的返回值。
# 不要删除题目、测试数据、预期结果和自查注释。
# 第一部分:理解函数可以赋值给变量
# 1. 定义 greet_agent(name) 函数。
# 2. 函数 return f"你好,{name}。",不要在函数内部 print()。
# 3. 把 greet_agent 函数本身赋值给变量 greeting_function赋值时不要写括号。
# 4. 调用 greeting_function("代码助手"),保存并输出返回值。
# 5. 预期结果:“你好,代码助手。”。
# greeting_function = greet_agent
# print(greeting_function("代码助手"))
# 第二部分:定义 log_call(func) 装饰器
# 1. 在 log_call() 内定义 wrapper(*args, **kwargs)。
# 2. 在 wrapper 上方使用 @wraps(func)。
# 3. wrapper 先输出 f"调用函数:{func.__name__}"。
# 4. 使用 func(*args, **kwargs) 调用原函数,并把返回值保存为 result。
# 5. wrapper return result不能丢失原函数返回值。
# 6. log_call() return wrapper注意不要写成 wrapper()。
# 第三部分:使用 @log_call
# 1. 定义 get_agent_name(agent) 函数。
# 2. 在函数上方写 @log_call。
# 3. 函数 return agent["name"]。
# 4. 调用 get_agent_name(enabled_agent),保存并输出结果。
# 5. 预期先输出“调用函数get_agent_name”再得到“代码助手”。
# 6. 检查 get_agent_name.__name__预期仍是 "get_agent_name"。
# print(get_agent_name(enabled_agent))
# print(get_agent_name.__name__)
# 第四部分:定义 require_enabled(func) 装饰器
# 1. 在 require_enabled() 内定义 wrapper(agent, *args, **kwargs)。
# 2. 在 wrapper 上方使用 @wraps(func)。
# 3. 如果 agent.get("enabled", False) 为 False
# 输出“Agent 已停用,不能执行任务。”并 return None。
# 4. 如果 Agent 已启用,调用 func(agent, *args, **kwargs) 并 return 原结果。
# 5. require_enabled() return wrapper。
# 第五部分:使用 @require_enabled
# 1. 定义 run_task(agent, task_name) 函数。
# 2. 在函数上方写 @require_enabled。
# 3. 函数 return f"{agent['name']} 正在执行:{task_name}"。
# 4. 传入 enabled_agent 和 "检查代码",预期返回:
# “代码助手 正在执行:检查代码”。
# 5. 传入 disabled_agent 和 "整理对话",预期输出停用提示并返回 None。
# print(run_task(enabled_agent ,"检查代码"))
# print(run_task(disabled_agent ,"整理对话"))
# 第六部分:定义 main() 函数
# 1. 完成第一部分的函数赋值实验,并输出问候结果。
# 2. 调用 get_agent_name(enabled_agent),保存并输出返回值。
# 3. 输出 get_agent_name.__name__确认 @wraps 保留了原函数名。
# 4. 分别使用启用和停用 Agent 调用 run_task()。
# 5. 保存并输出两个调用结果,停用 Agent 的结果应为 None。
# 6. 添加程序入口判断,直接运行本文件时调用 main()。
# 最终验收测试:
# 1. greeting_function 与 greet_agent 指向同一个函数;
# 2. greeting_function("代码助手") 返回正确文字;
# 3. get_agent_name() 调用前输出函数名称;
# 4. get_agent_name(enabled_agent) 返回“代码助手”;
# 5. get_agent_name.__name__ 仍是 "get_agent_name"
# 6. run_task(enabled_agent, "检查代码") 返回正确文字;
# 7. run_task(disabled_agent, "整理对话") 返回 None
# 8. 停用 Agent 不会执行原 run_task() 的函数主体;
# 9. 两个装饰器都能接收参数并保留原函数返回值。
# 完成后自查:
# 1. 是否理解函数名不加括号表示函数本身;
# 2. 是否理解函数名加括号表示立即调用函数;
# 3. 装饰器是否接收原函数并返回 wrapper
# 4. wrapper 是否调用并返回原函数结果;
# 5. 是否使用 *args 和 **kwargs 转发参数;
# 6. 是否使用 @wraps(func) 保留原函数信息;
# 7. 是否能解释 @log_call 与手动重新赋值的关系;
# 8. 是否保留了完整题目和验收说明。