昨天,我们用 for 循环让程序重复处理多个任务。可是循环里的代码如果在别处还要使用,继续复制粘贴会越来越难维护。
今天学习函数 def:给一段代码起名字,需要时通过名字调用。Agent 的搜索、计算、文件读取,本质上都可以先封装成函数工具。
今天完成 4 件事
1|理解函数定义与调用
2|分清形参与实参
3|掌握 return 返回值
4|完成学习建议工具
def greet():
print("欢迎开始今天的 Python 学习")
greet()def 是 Python 关键字,不能改名;greet 是函数名,可以换成更清楚的名字;圆括号、冒号和缩进都是固定语法。
程序先读取函数定义,但定义时不会执行缩进里的 print()。运行到 greet(),才真正进入函数体并输出一次。调用两次 greet(),函数体就执行两次。
def greet(name):
print(f"你好,{name},开始学习吧。")
greet("小白")
greet("阿明")定义区域里的 name 叫形式参数,简称形参;调用时传入的“小白”和“阿明”叫实际参数,简称实参。
第一次调用时,函数内部相当于临时得到 name = "小白";第二次调用时相当于得到 name = "阿明"。两次调用互不混淆。
def show_plan(topic, minutes):
print(f"今天学习 {topic},计划 {minutes} 分钟。")
show_plan("Python 函数", 45)调用时第一个实参进入 topic,第二个实参进入 minutes。如果误写成 show_plan(45, "Python 函数"),语法仍能运行,但意思错了,这是逻辑错误。
函数需要两个参数却只传一个,会触发 TypeError。这与变量不存在导致的 NameError 不同。
def add(a, b):
result = a + b
return result
total = add(8, 5)
print(total)add(8, 5) 的返回值是 13,因此这一行最终等价于 total = 13。return 执行后,本次函数调用立即结束。
如果函数里只有 print(result) 而没有 return result,屏幕虽然显示 13,但外部接收到的默认返回值是 None。
新建 day7_study_tool.py:
def make_study_advice(topic, minutes):
if minutes >= 60:
action = "完成一个小项目并整理笔记"
elif minutes >= 30:
action = "学习一个知识点并做一道练习"
else:
action = "先完成一个 10 分钟小任务"
return f"主题:{topic};建议:{action}。"
topic = input("今天学习什么?")
minutes = int(input("计划学习多少分钟?"))
advice = make_study_advice(topic, minutes)
print(advice)运行:
python day7_study_tool.py假设输入“函数”和 45,调用时 topic="函数"、minutes=45。第一个条件为 False,第二个为 True,函数返回“学习一个知识点并做一道练习”。
函数内部没有循环,因此三个条件只从上到下判断一遍。外部的 print(advice) 也只执行一次。
一个 Agent 不应该把搜索、计算、保存结果的代码全部堆在一起。更清楚的结构是:
def search_tool(keyword):
return f"正在搜索:{keyword}"
def calculator_tool(a, b):
return a + b函数名表示工具名称,参数表示工具输入,返回值表示工具结果。以后 Agent 只需要选择合适的函数并传入参数。
1. 忘记冒号:def greet() 语法不完整,会触发 SyntaxError;
2. 函数体没有缩进:Python 不知道哪些代码属于函数;
3. 只写定义却没有 greet():代码语法正确,但函数体一次也不执行;
4. 参数数量不匹配:函数需要两个参数,调用时只给一个,会触发 TypeError。
还要注意:函数名与变量名都由你命名,但调用时必须与定义完全一致。定义 make_advice() 却调用 make_advise(),会触发 NameError。
写一个 check_tool(tool_name, enabled) 函数:如果 enabled 为 True,返回“工具可用”;否则返回“工具暂不可用”。
分别调用两次:一次传入 ("搜索", True),一次传入 ("计算器", False),观察函数体各执行几次、每次参数保存的具体值是什么。
• def 用来定义函数,函数体只有在调用时才执行;
• 形参写在定义中,实参写在调用中;
• 多个参数默认按位置对应,数量不一致会触发 TypeError;
• return 把结果交给调用者,print() 只负责显示;
• 函数可以把 Agent 的一种能力封装成可重复调用的工具。
下一篇,我们学习字典 dict:为每个工具保存名称、说明和状态,建立 Agent 的工具档案。
完成练习后,欢迎留言:第 7 天完成。