学习前提
本章可作为该语言的起点,不要求先学网页开发。
本课完成后你能做什么
完成第一个脚本,解释变量绑定、字符串与数字的差异。
先理解机制
Python脚本是由解释器读取执行的文本文件,不是把代码写进网页就会运行。先安装官方Python发行版并在终端确认python3 --version;编辑器只是写代码的工具,实际使用哪个解释器需要单独确认。保留错误信息中的文件名和行号,有助于定位问题。
变量名绑定到对象,赋值不是数学等式。int用于整数,float用于近似小数,str用于文本;type可以观察类型。字符串12与整数12有不同操作规则。把外部文本转成数字是一次可能失败的操作,后续章节会专门处理异常。
Python用缩进表达代码块,同一级保持一致,不混用Tab与空格。print负责输出,f字符串把表达式结果嵌入文本。代码从上到下执行,因此先修改变量再输出,会看到新绑定的值,而不是之前的历史值。
先用确定的常量练习,再加入input,能把类型问题与输入等待分开。input返回字符串,不能因用户输入了数字就假定类型也是数字。不要使用eval把输入当代码求值;转换函数和明确规则更容易测试。
可运行示例
使用Python 3.11或更新版本,将代码保存为独立练习目录中的lesson.py,在该目录执行 python3 lesson.py;Windows也可使用 py lesson.py。示例只使用标准库。
name = "Honeysuck"
minutes = 25
sessions = 3
raw = "4"
print(f"{name}: {minutes * sessions} minutes")
print(type(raw).__name__, type(sessions).__name__)
print(int(raw) + sessions)
print(7 / 2, 7 // 2, 7 % 2)
推演与验证
输出75分钟、str int、7,以及3.5 3 1。把raw改成4.5再运行,int转换会失败;这是输入不符合整数格式,不是print失效。将sessions改为0,确认总时长变0且脚本仍正常结束。
常见错误与边界
整数除法//是向下取整,负数时不能简单理解为去掉小数。浮点数存在表示误差,不能把float当成所有金额计算的精确模型。变量命名不要覆盖print、list等内置名称。
动手练习
把学习时长改成用户可配置的常量,输出总分钟数和整小时、剩余分钟。分别验证0、59、60和125分钟。
参考解法与理由
小时用//60,余数用%60。先在纸上列出四组预期结果,再运行对照。输入验证与时长格式化可在后续提取成两个函数,不要混在一段难以复用的输出里。
深入实验:变量、对象与浅拷贝
列表复制后为什么修改仍会影响原列表?关键不是“Python随机共享内存”,而是你只复制了外层容器。下面建立两个层次的对象关系,在运行前画出每个名字指向谁。保存为lesson.py,用Python 3.11或以上运行。
original = [["HTML"], ["CSS"]]
alias = original
shallow = original.copy()
shallow[0].append("forms")
shallow.append(["JavaScript"])
print(original)
print(len(original), len(shallow))
print(alias is original, shallow is original)
assert original[0] is shallow[0]
independent = [row.copy() for row in original]
independent[0].append("tables")
assert "tables" not in original[0]
预期观察
依次输出[["HTML", "forms"], ["CSS"]]的Python列表表示、2 3、True False。Python通常用单引号显示字符串,内容等价。
原因、取舍与适用边界
alias和original是同一外层对象,所以is为真。shallow是新外层列表,但第0项仍指向同一个内层列表,append("forms")会被两边看到;给shallow追加新行则只改新外层。独立复制一层内嵌列表对本例足够,却不是任意深度数据的通用解法。深拷贝也不自动解决外部文件句柄等资源的语义,应先确定哪些状态需要独立。
进阶练习
把初始列表换成[[]] * 3,然后向第0行加入1,预测三行内容。如何创建三个独立空列表?
解法与推理
三行都显示[1],因为乘法重复的是同一个内层列表的引用。使用[[] for _ in range(3)],每次迭代才会创建新列表。用rows[0] is rows[1]检查身份,比仅比较初始空列表是否相等更有解释力。