正文
暂时不必把目标设成“学会所有语法”。这一篇先解决一个更具体的问题:怎样把“根据会议信息生成通知”写成电脑能够执行的步骤。
Python 是一种编程语言。编写 Python 程序,就是按照它的语法,描述数据和处理规则,再交给相应的运行环境执行。
这里的“运行环境”,可以先理解为能够执行 Python 代码的解释器,以及程序使用的相关资源。把代码写进文件,只是保存了处理步骤;还需要启动执行,程序才会真正处理数据。
你可以把代码放在编辑器中,保存为以 .py 结尾的文件,再用对应的 Python 运行环境执行;也可以在交互环境中输入一小段,立即观察结果。编辑器负责帮助书写,解释器负责执行,它们的职责不同。
先看一段很短的代码:
meeting_title = "项目例会"
start_time = "14:00"
notice = f"{meeting_title}将于{start_time}开始。"
print(notice)
第一行把名称 meeting_title 与一段文字关联起来,第二行保存开始时间。这里的名称叫变量名,等号表示赋值。给变量取一个能说明用途的名字,可以帮助人理解后面的程序。
引号里面的文字,叫字符串。项目名称是一段字符串,“14:00”也可以先作为字符串保存。电脑不会只凭这些字符,就自动完成时区换算或日期判断;需要怎样解释它们,要由后续程序决定。
第三行把两段资料放进通知句子。开头的 f 表示使用一种可插入表达式的字符串写法,花括号中的变量会被替换成对应值。这里生成的 notice 仍然是一段文字。
第四行调用 print,把结果显示出来。按这段代码提供的值,输出应当是“项目例会将于14:00开始。”这里的数据由我们直接写入代码,还没有连接真实日历。Python 的变量、字符串与输出
这几行说明了程序的一种基本结构:准备输入,执行处理,产生输出。生成通知时还可以加入检查,例如开始时间没有提供,就先说明缺少信息。
def build_notice(title, start_time):
if not start_time:
return "会议时间待确认。"
return f"{title}将于{start_time}开始。"
notice = build_notice("项目例会", "14:00")
这一段定义了一个叫 build_notice 的函数。函数把一段可以重复使用的处理过程起一个名字,后续用这个名字调用它。
括号中的 title 和 start_time 是函数参数,用来接收每次调用提供的内容。这里的参数是程序接口中的输入名称,与前面学习的神经网络可训练参数,讨论的是不同事情。
函数体中,if 表示根据条件选择处理分支。这里用 not start_time 检查输入是否为空等假值;如果条件成立,就返回“会议时间待确认。”否则,继续执行下面的通知生成。
return 把计算结果交回调用位置。最后一行实际调用函数,并把返回值关联到 notice。定义函数与调用函数,也需要分清:只写好定义,不会自动为每场会议生成通知。
冒号后面缩进的部分属于对应代码块。函数中的内容向右缩进,条件分支内部又多缩进一层,这些层次是 Python 语法的一部分,需要保持一致。条件判断与函数定义
上面的检查还很有限。“时间不是空的”不等于“时间格式有效”,更不等于“这就是正确会议的真实时间”。即使传入一段不合适的非空文字,函数也可能照样拼进通知。
这提醒我们,程序会执行已经写出的规则。需要核对哪些字段、怎样处理无效输入,都应该明确设计。后面的类型系统和数据校验,会继续补足这一部分。
如果有很多场会议,也不必把同一段处理复制许多遍。程序可以把会议记录组织成集合,再使用循环逐项处理。循环说明要重复什么,数据决定这次具体处理哪些项目。
循环同样需要边界。例如,遍历一份有限的会议列表,与不断等待新会议的服务,是不同的运行安排。不能因为代码里出现“重复”,就认为程序能够无限运行或者自动恢复中断。
当处理逐渐变多,还可以把相关函数放在模块中。模块可以先理解为组织 Python 代码的一种单位,很多情况下对应一个代码文件。通过导入,其他代码可以使用它提供的功能。
Python 也带有标准库,提供文件、日期、JSON 等常用能力。项目还可以使用另外安装的第三方包。标准库与第三方依赖的来源和管理方式不同,后面会单独学习怎样选择运行环境和记录依赖。
例如,程序生成通知之后,还需要把文字写进文件。显示到屏幕和保存到文件,是两个动作。前面的 print 只负责输出显示,没有自动生成可交付的文件。
一种文件写入方式如下:
with open("notice.txt", "x", encoding="utf-8") as file:
file.write(notice)
这里打开一个名为 notice.txt 的新文件,使用 UTF-8 编码保存文字。模式 x 表示排他创建:目标文件已经存在时,会报错,避免这段示例直接覆盖已有内容。
相对文件名会根据程序的当前工作目录解析,未必就是代码文件所在的目录。实际应用应当明确输出位置,而不是只看到文件名,就假定用户能在预期文件夹找到它。
with 帮助安排文件资源的使用范围。执行离开这个范围时,文件会被关闭。写入也可能因目录不存在、权限不足等原因失败,需要相应处理。文件打开方式与编码
因此,代码能运行,与它符合业务要求,也不是同一件事。一个程序可能顺利写出了通知,却使用了错误的会议资料;也可能内容正确,却写到了用户找不到的位置。
继续发展成真实应用时,可以把读取日历、生成内容和保存结果分别组织成清楚的函数。每个函数说明需要什么输入、返回什么结果、可能怎样失败,再由外层程序安排它们的配合。
如果需要大模型处理复杂语言,也可以通过已经接好的接口调用模型。Python 负责组织调用与后续操作,模型提供相关的语言能力。写一段 Python 程序,不等于重新训练了一个模型。
同样,Python 只是实现工具之一。Agent 也可以用其他语言开发。学习它,是为了掌握一种表达处理过程的方式,而不是把某种语言与 Agent 绑定成唯一选择。
初学时,可以先观察几类问题:变量此刻关联的值是什么,函数收到哪些输入,条件为何进入某个分支,返回值去了哪里,以及哪些操作实际影响了文件或外部系统。
这些问题会让代码从“一段看不懂的英文”变成可追踪的处理过程。遇到错误提示时,也可以从具体输入和执行位置查起,而不是只看程序最后有没有输出一句成功。
后面再学习接口、异步和异常处理时,我们会在这个基础上继续增加能力。现在先把“数据进入函数,按规则处理,再产生结果”的过程理解清楚。
下一篇进入 02.02:类型系统与数据结构,继续看文字、数字、真假值,以及列表和字典等组织方式,为什么会影响程序能够进行哪些操作。
当前学习编号:02.01 Python 编程。
下一学习编号:02.02 类型系统与数据结构。后续还有其他学习编号。
关联分支:数据与程序组织对应 02.02 类型系统与数据结构、02.03 算法复杂度与资源开销、02.09 异常处理与资源清理、02.11 依赖管理与环境隔离、02.12 单元测试与集成测试。
与 Agent 接入的关系,对应 02.04 HTTP 与 REST API、02.05 JSON 与序列化、02.06 Schema 与数据校验、16.05 工具调用请求与实际执行的区别。变量、赋值、函数、作用域、条件、循环、模块和文件读写,是本编号继续下钻时的支系知识。