5.2 程序结构——分支语句¶
内容梗概¶
本课讲分支语句 if / elif / else。通过一个“输入年龄判断是否成年”的小例子引入内置函数 input(),并现场纠正了一个易错点:input() 返回的永远是字符串,比较前必须手动 int() 转换。随后用同学在群里提出的“表白程序”(“不喜欢”按钮永远点不到)作为综合案例,用 Python 内置的 tkinter 和 random 库实现了一个带界面的程序,借此讲解了窗口程序的消息循环/事件驱动机制、按钮的 command 回调与 <Enter> 事件绑定,以及如何用复杂的组合分支条件保证按钮随机移动后不压在鼠标下。
知识点详解¶
if / elif / else 基本结构¶
if-else很好理解,前面讲布尔逻辑时已大量使用 (约 00:00)。elif是 "else if" 的缩写,为了让代码短一点(且elif与else正好同宽,对齐美观)(约 04:02)。- 答疑:
raw_input是 Python 2 的函数,Python 3 中没有,留待课后确认 (约 04:34)。
input() 内置函数(重点纠错)¶
input("提示语"):先输出参数中的提示语,然后等待用户在命令行输入内容,回车结束 (约 00:34)。- 关键易错点(老师现场“直播事故”后纠正,约 02:11–03:34):
input()**不会**自动把输入转成数字,返回值永远是str字符串类型。要当数字比较必须先手动转换:int(input(...))。可用type()查看类型验证。 - 变量命名规范:变量名要有意义(如这里该叫
age而不是condition),不要用 a/b/c 这类名字,这也是上次作业批改时给很多同学提的要求 (约 03:34)。
窗口程序与消息循环(结合表白程序讲解)¶
- 带界面的程序(窗口程序)背后是一套**消息循环**机制 (约 16:15):
- 用户在界面上的所有操作(移动鼠标、点击、输入、缩放窗口)都是消息/事件(event),被放入**消息队列**。
- 程序有一个大循环不断从队列中取出消息,交给对应的**消息处理函数**处理。
window.mainloop()就是开启这个主消息循环。- tkinter 要点:
- 用
import tkinter as tk起别名减少打字量 (约 09:52)。 tk.Tk()创建窗体对象;window.title(...)设标题;window.geometry('800x600')设分辨率(800×600 像素)。tk.Button(window, text='不喜欢', command=hitme)创建按钮:第一个参数指明属于哪个窗口;text是按钮上显示的文本;command传入一个**函数名**,按钮被点击时执行该函数(回调)。- 按钮创建后必须调用
.pack()才会显示在窗口上。 按钮.bind('<Enter>', escape)为按钮绑定“鼠标进入”事件:鼠标一碰到按钮就调用escape函数——这是按钮“乱跑”的关键;去掉这行代码按钮就能被点到 (约 12:07–15:09)。
复杂组合分支条件的设计¶
- 按钮随机移动的逻辑:
escape函数获取按钮位置(左上角坐标 x, y)和宽高,捕获鼠标位置 MouseX/MouseY,然后在窗口范围(x: 0–800,y: 0–600)内随机新坐标 (约 19:11–24:56)。 - 为什么不能无脑随机:随机坐标可能正好盖住鼠标,按钮就“自投罗网”了。所以每次随机后要用组合条件判断新位置是否会压到鼠标:
- 横向:
x < MouseX时还需x + 宽度 < MouseX;若x本身就在鼠标右侧(x > MouseX)则无需考虑宽度。 - 纵向同理。只有 x、y 两个方向都避开鼠标,新位置才合法。
- 这个案例放在“分支”一节的原因:展示了用多个条件组合出复杂判断条件的实际用途。
示例与演示¶
- 年龄判断示例:
age = int(input("请输入你的年龄")),配合if age >= 18: ... else: ...判断是否成年(演示了 input 不转 int 会出错的“直播事故”及修复)。 - 表白程序综合演示:
- 结构:两个消息处理函数(
hitme点击回调打印“不喜欢”;escape鼠标进入时移动按钮)+ 很短的程序主体(建窗体、建按钮、pack、绑定事件、mainloop)。 - 演示去掉
<Enter>绑定后按钮可点击、打印“不喜欢”;加上绑定后按钮永远点不到。 - 白板上画图讲解消息循环/消息队列,以及坐标判断条件的几何含义。
重点与难点¶
input()永远返回字符串,数字比较前必须int()转换——老师自己都会讲错,务必牢记。- 变量命名要有意义,从短代码开始养成习惯。
- 理解事件驱动模型:消息循环 + 消息队列 + 消息处理函数(回调),这是所有 GUI 程序的通用逻辑。
- 复杂分支条件来自多个简单条件的组合(and/or),要结合几何/业务含义逐一分析。
command=和bind()传的是函数名(不是函数调用,不加括号)。
关联内容¶
- 前置:5.1 布尔逻辑(判断条件、短路运算、比较运算)是本课分支条件的直接基础;
type()来自数据类型章节。 - 本课的函数回调(
hitme、escape)在 5.4 函数一节继续被用作 lambda 匿名函数的例子。 - 表白程序中的死循环 +
break用法在 5.3 循环语句一节被回顾;pass占位符也以本课的hitme函数为例讲解。 - tkinter 只用了 Python 内置库,呼应课程“不装第三方库也能写界面程序”的理念;后续实践部分会讲更多实例(如发邮件)。