开头如果你点进这篇笔记大概率和我一样正处在学编程的“第二天”这个尴尬位置。第一天装好了环境、跑通了第一行print(Hello World)感觉自己行了第二天一打开教程面对变量、数据类型、运算符、条件判断、循环……整个人又懵了。这很正常我当天学完的感觉是语法都认识组合起来就手抖。这篇笔记就是我第二天学习的完整记录包含我踩过的坑、整理出来的避坑清单以及一个能跑通的小项目。它适合谁适合和我一样零基础起步、刚好啃到第二天内容的朋友也适合学过一遍但想查漏补缺的初学者。内容不绕弯子直接讲核心语法怎么理解、怎么写不出错、出了问题怎么排查。我选择记录“第二天”而不是“第一天”因为第一天的新鲜感掩盖了太多问题照着敲代码谁都会可第二天开始要求你自己写逻辑问题才真正暴露出来。所以这篇笔记的重点不是罗列语法点而是把“为什么会报错”“为什么这么写”“怎么改才对”讲清楚让你学完以后不是背了一堆规则而是真正能上手写点小东西。1. 学习规划为什么第二天就要碰“硬骨头”1.1 第一天的铺垫到底铺了什么先回顾一下第一天做的事因为第二天的内容全部建立在它上面。第一天主要解决三件事装好 Python 解释器、选一个趁手的编辑器、跑通第一个程序。我当时用的是 Python 3.11编辑器选了 VS Code装完官方 Python 插件。第一天结束时的状态是能在终端里用python命令进入交互模式也能在 VS Code 里写好.py文件按运行按钮看到输出。这里想多说一句环境的事。很多新手纠结“用 Python 2 还是 Python 3”“用 PyCharm 还是 VS Code”我建议直接 Python 3 加 VS Code理由只有一条社区里现在能找到的资料和报错解决方案九成以上都是基于这套组合的。你遇到问题去搜索答案几乎都能直接照抄这对新手来说比工具本身好不好用更重要。而且 VS Code 的插件市场里有 Python 官方插件装完以后代码补全、语法检查、运行调试全都有了省心。第一天的另一个收获是学会了看报错信息。别小看这件事第二天所有“卡壳”时刻都是靠读报错信息脱困的。我的方法很笨但很有效报错出现以后先看最后一行那行通常会告诉你错误类型和出错位置比如NameError: name x is not defined意思就是“x 这个名字没定义过”。看到这种错误第一反应不是慌而是去检查自己是不是打错了变量名或者变量的赋值语句是不是没执行到。1.2 第二天的目标拆解与学习路线第二天我给自己定的学习目标是掌握变量与基础数据类型、运算符、条件判断和循环最后写一个猜数字小游戏收尾。这个目标不是拍脑袋定的是因为这四块内容正好构成写任何程序都要用到的最小骨架——程序本质上就是“存数据、算数据、根据条件做决策、重复做某件事”。学完这些你就具备了读懂大多数入门代码的基础。学习路线上我用了“先主干后细节”的方式。上午啃变量和数据类型下午啃运算符和条件判断晚上啃循环并完成小项目。这个安排有个讲究变量和数据类型是地基运算符和条件判断是墙循环是屋顶小项目是把它们盖成房子。如果顺序反了比如一上来就学循环你会发现循环里全是变量和判断的语法每个地方都要回头翻学习效率极低。我个人的体会是第二天最容易犯的错误是“贪多”。网上教程动辄一章列十几个知识点每个都举三五个例子看到后面脑子直接过载。所以我给自己定了个规矩每个知识点只记一个核心用法和一个典型坑其他花式写法暂时不管。等小项目做完了发现哪个知识点用得上再回头深入。事实证明这个策略很管用因为写项目的时候你会主动回忆这些知识记忆比单纯看教程牢固得多。1.3 学习方法为什么我坚持“写废代码”来学我第二天的学习方法听起来有点反常规不追求把示例代码一次敲对而是故意“写错”。比如学变量的时候我会故意把变量名拼错故意把一个字符串和一个整数相加故意漏写冒号然后观察报错信息长什么样。这么做的好处是错误在我“可控”的情况下亲手制造出来我对错误信息的敏感度会大幅提高。等到后面自己写代码真出错时扫一眼报错信息就能定位问题而不至于像无头苍蝇一样乱猜。这种方法的心理学依据其实很简单人对“自己亲手踩过的坑”的记忆远比对“别人反复叮嘱的注意事项”深刻。所以我建议你学的时候别怕报错反而要主动“惹恼”解释器。每次报错都是一次免费的教学它会告诉你语法上的边界在哪里。我会在后面的章节里把我当天实际遇到的报错和排查过程完整写出来。那些报错信息我至今印象很深因为它们几乎覆盖了初学者最常见的几种问题你如果照着学大概率也会撞上其中一两样到时候回来翻这篇笔记能少走很多弯路。2. 核心语法逐项拆解变量、类型与运算符2.1 变量与赋值的本质不是“盒子”是“标签”很多人解释变量时会说“变量是一个盒子里面装着数据”。这个类比我当时听着觉得对可一写代码就出问题——因为“盒子”这个思维会误导你理解变量重新赋值的现象。比如这两行代码a 10 a 20如果用“盒子”来理解你会觉得第二个a 20是把盒子里原来的 10 倒掉换成 20。这个理解在这个例子里没错但一旦遇到多个变量指向同一个数据就解释不通了。更准确的说法是变量是一个“标签”而数据对象是真正存在内存里的东西赋值操作是把标签贴到数据上。你可以把多个标签贴在同一个数据上也可以随时把一个标签揭下来贴到别处。举个生活化的例子想象你养了一只猫叫“咪咪”后来你又给它起名叫“小咪”。名字变了猫还是同一只猫。在 Python 里a [1, 2, 3]和b a这两行代码a和b就是同一只“猫”的两个名字修改a的内容b也会跟着变因为它们指向的是同一个列表对象。这个知识点在第二天可能用不上但如果你一开始就建立了正确的“标签”模型后面学列表、字典、函数传参时会省掉大量困惑。第二天的实操建议是把变量名当成“给数据起的名字”起名要尽量有意义。比如age、score就比a、b好得多。我当时写猜数字游戏时用了secret和guess这两个名字代码读起来就像人话写起来也不会搞混谁是谁。新手最容易犯的错是变量名随手起成x、y、tmp代码一长自己都看不懂。2.2 基础数据类型五种常客的脾气和“坑点”Python 里最常用的基础数据类型有五类整数int、浮点数float、字符串str、布尔值bool和空值None。第二天的任务是把它们各自的脾气摸清楚尤其是它们之间的区别。整数和浮点数最朴素的坑是除法。Python 里/号做除法得到的一定是浮点数哪怕能整除10 / 2的结果是5.0而不是5。而//是整除10 // 2得到510 // 3得到3它会向下取整。另一个坑是浮点数的精度问题0.1 0.2的结果是0.30000000000000004这不是 Python 的 bug而是所有用二进制表示十进制的语言都有的现象。初学者不用深究原理但要知道判断浮点数是否相等时别用而要看它们差的绝对值是否足够小。字符串的坑主要在引号和拼接。Python 里单引号和双引号都表示字符串但如果字符串里本身就包含引号就要小心。比如想表示He said hello用双引号包整个字符串会把引号搞乱解决办法是用单引号包整体或者反过来再或者用转义字符\。我当时在这个地方卡了几分钟。字符串拼接用的是但要注意字符串只能和字符串拼接字符串不能直接和整数拼接这是当天我遇到的第一个报错后面第 4 章会详细讲。布尔值只有两个True和False。它最常出现在比较运算的结果里比如3 2的结果就是True。还有一个隐蔽的知识点在 Python 中数字0、空字符串、空列表[]在用作条件判断时会被当成False其他大多数值都会被当成True。这个特性后面学if语句时会经常用到。至于None它表示“什么都不存”常用来给变量一个初始占位值和0、空字符串有本质区别别混为一谈。2.3 运算符优先级让代码按你预期的方式计算运算符这部分形式上很好懂无非是加减乘除、比较大小、逻辑与或非真正容易出错的是优先级——也就是多个运算符混在一起时Python 先算哪个。我记得学基础知识点时的排布顺序是先复习算术运算符再从简单的not or and组合判断逻辑最后才上优先级表格。实际操作中有个更简单的办法严格使用括号。如果你不确定优先级就给先算的部分加上括号既能让代码符合预期又让读代码的人一眼看懂你的意图。我用一个小例子说明优先级陷阱。条件是“只有当年龄大于 18 且分数大于 60或者年龄等于 18 且分数大于 80 时才通过”写成代码很容易犯一个错# 容易误写这样写会被解释为 age 18 且 (score 60 或 age 18) 且 score 80 passed age 18 and score 60 or age 18 and score 80这行代码实际上能正常运行但它的运算顺序未必符合你的直观理解。and的优先级比or高所以上面这行会被解释为(age 18 and score 60) or (age 18 and score 80)。如果这恰好是你想要的逻辑那没问题但如果你心里想的是别的分组结果就会悄悄跑偏。所以我的建议是逻辑判断稍复杂一点就加括号不要赌自己记得住优先级。算术运算符方面Python 里有个比较反直觉的“坑”三个运算符连续计算时按从左到右但幂运算**是从右往左的。2 ** 3 ** 2的结果是512因为它先算3 ** 2 9再算2 ** 9 512。这种写法在实际代码里非常罕见万一你也遇到了带连续幂运算的题直接加括号就能避免歧义这也是相对稳妥的处理方式。2.4 类型转换显式转换和隐式转换的分寸类型转换是第二天必学的操作因为程序在运行中经常需要把一种类型的数据变成另一种。最常用的是三个函数int()、float()、str()分别用于转成整数、浮点数和字符串。比如用户输入的内容在 Python 3 里一律是字符串要拿去做数学计算就得先转成整数或浮点数price input(请输入价格) # 这里返回的是字符串 total int(price) * 2 # 必须先转换成整数才能相乘显式转换要注意两个坑。第一个字符串里不是纯数字时int()会直接报错比如int(12a)就会抛ValueError。所以调用int()之前最好先确认字符串内容是纯数字否则要考虑用try...except捕获异常。第二个int()截断浮点数时是朝零取整的int(3.9)结果是3不会四舍五入。要四舍五入得用round()函数。隐式转换则主要发生在混合运算里。1 2.0的结果是3.0因为整数会自动转成浮点数参与运算这就是隐式转换。布尔值参与运算时True会被当成1False会被当成0所以True 1的结果是2。这些冷知识平时用不到但笔试面试爱考而且理解它们能帮你读懂一些奇怪的代码知道总没坏处。3. 流程控制从顺序到分支再到循环3.1 if/elif/else条件判断的结构与缩进的致命性学完变量和类型接着就是让程序“长脑子”的条件判断。Python 的if语句结构和别的语言最大的不同在于它不是用花括号{}划分代码块而是用缩进。同一个缩进级别的代码属于同一个代码块这一条规则让很多第一次接触 Python 的人栽了跟头。我当时犯过一个很典型的错。我的代码原本想表达“分数大于等于 60 就是及格否则不及格”但因为缩进多按了一下空格导致print(不及格)被缩进了if的代码块里结果不管分数多少屏幕上都会同时打印“及格”和“不及格”。这种错误不会报语法错因为逻辑上它是合法的但它会让程序行为完全偏离你的意图。排查这类问题的核心方法就是把缩进调到一眼能看出层级。关于分支结构的写法我直接给了自己一条铁律每个if后面必须有冒号代码块保持统一缩进最好是 4 个空格判断条件不需要加括号但加了也不错。elif是else if的缩写用来表达“否则如果”可以连续写多个。else是最终的兜底分支可写可不写。写多分支时有个细节Python 会从上到下挨个判断命中一个分支后后面所有分支都不会再执行。所以顺序很重要比如判断成绩等级时要先判断 90再判断 60如果把顺序写反95分就会先命中低等级分支。3.2 while 循环与 for 循环什么时候用谁循环的作用是让某段代码重复执行。Python 里有两类循环while循环和for循环。第二天的核心任务是搞清楚它们的适用场景。while循环的格式是count 0 while count 5: print(当前计数:, count) count count 1它的特点是只要条件为真就不断执行循环体。这种循环适合“不知道要重复多少次只知道满足什么条件就停”的场景比如让用户反复输入直到输对为止。while最大的风险是死循环如果循环体里没有任何语句改变条件里用到的变量条件永远为真程序就会无限运行下去。我当天就踩过这个坑具体的排查过程放在下一章。for循环更适合“明确知道要遍历多少数据”的场景比如遍历一个列表、一个字符串或者用range()函数生成一串数字for i in range(5): print(第, i, 次)range(5)会生成0, 1, 2, 3, 4这五个数字注意它不包含 5。range(1, 6)则是从 1 到 5。这个“包前不包后”的规则是新手常记混的点我建议你就死记range(开始, 结束)结束的那个数取不到。我的选择标准很简单能数得清次数、能列出要处理的东西就用for次数不确定、要看条件成立与否才决定是否继续的就用while。猜数字游戏里用户要猜几次是未知的所以我用while打印一个列表里的所有元素明确知道有几个我用for。3.3 break 与 continue控制循环的“刹车”和“跳过”循环体里经常需要两个控制语句break和continue。break的作用是“立刻结束整个循环”不管循环条件还成不成立直接跳出continue的作用是“跳过本次循环的剩余代码直接进入下一次循环”。这俩的差别我一开始总是混后来用一句话记住了break是退出整个循环continue只是跳过当前这一轮。举个例子。遍历1到10遇到数字5就想结束用break遇到数字5想跳过不打印但继续后面的数字用continue。代码如下for i in range(1, 11): if i 5: break # 打印 1 2 3 4 后整个循环结束 print(i) for i in range(1, 11): if i 5: continue # 不打印 5但 6 7 8 9 10 照常打印 print(i)注意break和continue只能作用于它们所在的那一层循环。如果你写了嵌套循环循环里套循环break只会退出内层循环外层还会继续。这个知识点第二天用不太上但提前知道能避免很多误解。break的实际应用场景很典型猜数字游戏里用户猜中数字后就要结束游戏如果不用break就得靠循环条件的复杂逻辑来控制代码会绕很多。所以当你想写的跳出条件比较复杂时优先考虑用break加一个永远为真的while True搭配这是 Python 里一个很常见的模式后面会看到。3.4 当天小项目猜数字游戏从拆解到跑通第二天晚上我把白天学的所有知识点揉进了一个小项目猜数字游戏。游戏规则很简单程序随机生成一个 1 到 100 之间的整数用户输入数字猜程序提示“大了”或“小了”直到猜中为止最后显示猜的次数。这个项目麻雀虽小却覆盖了变量、类型转换、条件判断、循环、break、random模块的导入与使用。完整代码如下import random secret random.randint(1, 100) attempts 0 print(我已经想好了一个 1 到 100 之间的数字快来猜吧) while True: guess_text input(请输入你猜的数字) guess int(guess_text) attempts attempts 1 if guess secret: print(大了再猜小一点。) elif guess secret: print(小了再猜大一点。) else: print(恭喜你猜对了你一共猜了, attempts, 次。) break写这个项目时有几个点值得单独说一下。第一random.randint(1, 100)会生成包含 1 和 100 在内的随机整数这是猜数字的核心。第二input()返回的是字符串所以必须用int(guess_text)转换后才能和secret整数比较大小如果不转换和比较的就是字符串结果会完全乱套。第三while True加break的结构让“退出循环”的逻辑集中在猜中的那一刻代码看起来清爽。跑通这个小游戏时我第一次感受到“自己写的东西真的有用”的快感。这不只是一个学习练习它验证了白天的所有知识点是能组合起来的。我的建议是学流程控制的当天一定要做一个小项目哪怕比猜数字更简单——比如打印九九乘法表。有没有这个项目学习效果是天差地别的。4. 实操记录当天练习中出现的问题与排查4.1 问题一字符串和整数强行拼接导致 TypeError当天练习的第一次报错发生在写个人信息输出的练习里。我当时写了这样一行age 18 print(我今年 age 岁)运行后报错信息是TypeError: can only concatenate str (not int) to str翻译过来就是只能用字符串去拼接字符串不能把整数直接拼进字符串。这个报错信息其实已经把解决方案暗示得很清楚了——你要么把age转成字符串要么换成别的方式输出。我当时的修正方案是print(我今年 str(age) 岁)后来我又学了更省事的写法用逗号隔开多个值让print自动加空格输出以及用f-string格式化print(我今年, age, 岁) print(f我今年{age}岁)f-string是我学完后最推荐的一种方式花括号里可以直接写变量名Python 会自动把它的值转成字符串拼进去干净利落。处理这个问题的核心心得是报错信息里往往藏着“操作数类型”的关键词看到str和int出现在一起不用查资料马上就能判断是类型不匹配。4.2 问题二while 循环忘了更新变量程序直接死循环第二个问题是在练习while循环时遇到的。我写了一个想倒计时的程序count 5 while count 0: print(count)运行以后终端里噼里啪啦地无限输出5我第一反应是按 CtrlC 强制终止。之后检查代码才发现循环体里少写了count count - 1导致count永远是5条件count 0永远成立死循环就这样形成了。这个教训非常典型几乎每个初学者都会踩一次。while循环的循环体里一定要有语句让条件涉及的变量朝“让条件变假”的方向改变。至于如何定位这个错误当时我用了一个笨办法在循环体里加一行print(循环执行中)发现这行被无限打印立刻就能确认是死循环。排查完后我把教训总结成一句话写while时先问自己“条件里的变量会不会变”如果不会那一定有问题。另外补充一个安全小技巧如果你担心程序死循环可以先在循环体开头加一个计数器当计数器超过一定值时就自动break。这在写复杂代码时是保住电脑的保命手段。我后来写很多临时测试脚本都会先加这么个保险运行确认没问题了再删掉。4.3 问题三缩进错位逻辑正确却运行结果诡异第三个问题最隐蔽因为程序能正常跑不报任何错误但结果就是不对。我当时写的是输入分数判断等级的练习代码长这样score 75 if score 60: print(及格) print(继续加油) print(程序结束)这个写法其实是对的但我有一次多按了两次空格把最后一行print(程序结束)也缩进到了if下面。从逻辑上看这行就变成只有及格才会执行。结果是输入 75 时“程序结束”正常打印输入 50 时“程序结束”消失了。这种问题通过看代码不容易发现尤其是代码一大。我的排查方法是“注释法”先把疑似出问题的代码行前面加#注释掉再运行看行为变化。如果注释掉后“程序结束”恢复正常就说明问题就出在那行的缩进上。修法也很简单把缩进退回去让它和if保持同一层级。这个案例给我的启发是Python 的缩进不只是“好看”的规范它是语法的一部分直接决定代码的归属关系。现在很多编辑器比如 VS Code都能让缩进可视化如果你也总在这上面栽跟头可以打开编辑器的“渲染空白字符”选项把空格和制表符显示出来一眼就能看清。4.4 排查思路把“猜问题”变成“看信息”当天解决这三个问题之后我发现它们背后有一套共同的排查思路写出来分享给你。遇到程序不对时别急着改代码瞎试按下面三步走先读报错信息的最后一行。它告诉你错误类型和出错位置能直接定位到文件名的行号比如line 5就从第 5 行附近找问题。再看报错信息里的描述。它往往直接说明了矛盾所在比如“不能把整数拼到字符串里”照着改就行。如果程序不报错但结果不对那是逻辑问题用“加打印”的方式辅助排查。在变量变化的关键位置打印出当前值观察运行过程符不符合预期。这三步里最值得刻意练习的是第三步。初学者遇到结果不对第一反应通常是盯着代码看觉得自己逻辑没问题。但代码不会骗人结果不对就是逻辑有漏洞。最好的办法是让程序把中间过程“说出来”打印出来的值会直接告诉你思路在哪里断了。我把这种方法叫作“给程序装摄像头”是我排查问题时的首选手段之后写更复杂的程序也多亏了这个习惯。5. 避坑清单与学习方法沉淀5.1 新手最容易踩的五个坑速查表把当天的问题整理一遍后我总结了五个最高频的坑做成表格放在下面方便你学的时候对照自查坑点典型现象正确做法变量名拼写不一致报NameError说某个名字没定义起名后统一用复制粘贴别手打字符串和整数直接拼接报TypeError: can only concatenate str...用str()转换或用f-stringwhile循环变量不更新程序卡死无限输出循环体内必须改变条件变量缩进层级不对不报错但结果离谱统一用 4 个空格缩进开渲染空白用判断浮点相等明明该相等却不相等比较差值绝对值是否小于 0.0001这五个坑里前三个只要碰过一次就会长记性后两个属于“不报错但坑人”的类型更要靠主动练习去建立敏感度。我的建议是学完一章就翻一次这个表看看自己有没有踩过类似的踩过就打个勾相当于给自己的知识漏洞做个标记。还有一个容易被忽略的习惯代码里中文标点和英文标点混用。input(请输入)里如果冒号用的是中文全角冒号Python 会直接报语法错误提示一个奇怪的非法字符。这个问题在中文输入法环境下特别常见如果你看到SyntaxError: invalid character先检查标点是不是全角的。5.2 当日高效学习法费曼输出加错误笔记学完一天我复盘时发现两个方法对消化知识特别有用一个是费曼输出法一个是错误笔记。费曼输出法说白了一句话能不能用最简单的话把知识讲给别人听是检验自己懂没懂的标准。我当天的做法是学完一个知识点就假装在给一个完全不懂的朋友发微信解释。比如解释for循环我会说“for 循环就像点名列表里有几个人就按顺序点到几个人”。如果我发现自己解释得支支吾吾说明这个知识点的理解还是有漏洞马上回去翻教程。这种自我检验比“看完了”“记住了”可靠得多。错误笔记则是把当天所有踩过的坑记录下来格式统一是错误现象、报错信息、原因、正确写法、注意事项五部分。比如字符串拼接那条笔记我会记下完整的报错堆栈方便以后搜索。这些笔记现在回看已经成了我自己的“错题本”比任何网上的避坑文章都贴合自己的薄弱点。令人惊讶的是把错误写下来这个动作本身就能强化记忆后面写代码时那些曾经栽过跟头的地方我会格外小心几乎没再犯过同样的错。5.3 第二天的检验标准学到什么程度算过关学习不能稀里糊涂地“感觉学会了”得有一个可量化的检验标准。我给自己定的是三个测试全部通过才算第二天真正过关第一能不能不看任何资料默写出五种基础数据类型并说出各自的典型踩坑点。第二能不能手写一个完整的if/elif/else分支和一个for循环并正确解释缩进的含义。第三能不能独立完成一个猜数字游戏从零写起不查任何资料保证运行结果正确。我会建议你也给自己设置类似的检验标准因为“看懂”和“会写”之间的距离比你以为的大得多。我当天的体会是看教程时每个点都懂合上书写代码时却频频卡壳——这是再正常不过的现象检验标准就是帮你直面这个差距的工具。卡壳本身不是坏事卡壳之后的排查过程才是第二天最宝贵的收获。最后再分享一个小技巧学第二天的内容时可以顺带把“伸手就能查”的东西背下来比如range()的用法、f-string的写法、random.randint的用法。这些高频小语法点背下来以后写代码不需要频繁中断去查文档流畅度会提升好几个档次。如果你时间充裕还可以试试把猜数字游戏改成“猜单词游戏”在基础版本上加一点自己的变化那种成就感会让你对第三天的学习充满期待。我自己的体会是编程学习最忌讳“只看不写”第二天的内容恰恰是动手价值最大的一天脚踏实地把每个例子敲一遍比任何技巧都管用。