
第二天打开电脑继续学Python说实话比第一天有意思但也更容易怀疑自己了。第一天装完环境、复制了两行“hello world”自己压根没弄明白为什么能输出。第二天打算正经学点基础语法结果光环境变量就折腾了好一阵。这篇就把第二天踩过的坑、看懂了的代码以及几个让学习没那么枯燥的小练习整理出来给同样处于python学习起步阶段的朋友参考。1. 开场三小时先跟环境变量和终端打了场交道1.1 python命令为什么突然“失灵”了第二天我一开始没急着写代码而是想把昨天的内容重新跑一遍。打开VS Code新建了一个文件写了句print(hello python)点运行没问题能输出。但当我打开系统终端或者换到cmd窗口输入python --version它却提示“不是内部或外部命令”。这个场景太典型了。搜一下“python 不是内部或外部命令”能翻出几万条提问几乎每个入门的人都会遇到。原因是这样的系统里安装软件时安装包默认会把应用程序放到某个目录但系统并不知道自己去哪里找它。Windows系统查找命令时只会按照“环境变量PATH”里记录的路径逐个去翻。如果你的Python安装目录不在这个列表里那终端里敲python就自然找不到。我当时是勾了安装时那个“Add Python to PATH”选项的为什么还是不行后来发现装的时候勾了但安装到的目录跟系统PATH里指向的目录不一致。比如装的是Python 3.12而旧版本残留的环境变量指向的是3.9的目录又或者安装时选了“仅当前用户安装”路径落在AppData\Local\Programs\Python\Python312\但系统环境变量里根本没有这一条。所以第二天上午等于补了一课学习Python的第一步不是背语法而是先搞清楚你自己的电脑怎么找到Python。1.2 把Python目录加进PATH的完整操作我当时是按下面这组步骤解决的Windows系统大致都是这个路径按下Win R输入sysdm.cpl回车打开“系统属性”。切到“高级”选项卡点右下角的“环境变量”。在下方的“系统变量”列表里找到Path双击打开。点“新建”把你Python的安装目录加进去。我的是C:\Users\用户名\AppData\Local\Programs\Python\Python312\。再点一次“新建”把同目录下的Scripts文件夹也加进去。比如C:\Users\用户名\AppData\Local\Programs\Python\Python312\Scripts\。全部点确定重新开一个终端窗口输python --version验证。这里有个细节值得多说一句Scripts目录一定要加。以后用pip install装的很多工具可执行文件都会放在这个目录里。不加的话你可能会遇到“明明用pip装好了某个包但终端敲命令却说找不到”的诡异情况。很多初学者卡在这一步半天排查不出来其实就是少了Scripts。验证的时候我建议分两步走。先执行python --version再执行pip --version两个都能正常显示版本才算环境彻底干净了。我试过只验证了python结果后来装库时才发现pip也是坏的又来回折腾了一轮。1.3 终端和编辑器里跑的Python可能是“两个不同的东西”除了PATH问题还有另一个容易踩的坑在VS Code里点“运行”能正常执行但在系统终端里就不行。这通常是因为VS Code里的Python解释器路径和终端里调用的Python路径不一致。VS Code装完Python扩展后会自动选择它认为合适的解释器你可以在VS Code右下角状态栏看到当前用的是哪个Python版本。如果你电脑里同时装了多个Python版本那情况会更热闹。我见过一个朋友的电脑Microsoft Store版Python和官网安装版Python同时存在VS Code默认用了Store版终端里调用的却是另一个版本两边sys.version都不一样。后面装第三方库时经常出现“VS Code里导入某库失败终端里却能正常导入”的怪事。第二个经验就是先统一解释器。打开VS Code的命令面板Ctrl Shift P输入Python: Select Interpreter把解释器路径跟你终端里where python查到的路径改成同一个。大多数莫名其妙的“为什么我能运行你不能”问题都是解释器不一致引起的。2. 真正把print和变量弄明白之后写代码才有感觉2.1 第一段正经代码环境搞定后我写下了第二天的第一段正经代码name 小明 age 18 print(我叫 name 今年 str(age) 岁)输出我叫小明今年18岁看是看懂了但我不太满足于“看得懂”。我试着把str(age)去掉直接写print(我叫 name 今年 age 岁)报错了TypeError: can only concatenate str (not int) to str这个报错成了我第二天最好的老师。它让我真正理解了字符串和数字是两种类型不能直接相加拼接。可能有人会觉得这种报错很烦但我后来发现刚学编程时多踩几个这种简单的坑反而比顺利跑通代码更让人印象深刻。2.2 print的“隐藏功能”第二天我花了不少时间折腾print函数因为它太常用了但它的细节比想象中多。第一个细节是sep参数。默认情况下print里多个值之间用空格分隔print(Python, 学习, 第二天)输出Python 学习 第二天想换成别的分隔符比如逗号这里容易出现“其实想要逗号但是默认空格”的情况print(Python, 学习, 第二天, sep)输出Python学习第二天第二个细节是end参数。默认print每次输出完会换行。如果把end改成空字符串它就不会换行了print(正在加载, end) print(...完成)输出正在加载...完成这个功能在以后写进度指示、写命令行小工具时特别实用。我之前看到别人写的脚本里输出一行日志后不换行当时还不理解为啥可以这样第二天自己试过之后才明白原来就是end参数的作用。第三个容易被忽略的点是print和return是完全不同的。print是把内容“显示”到控制台return是把值“交还给”函数调用处。第二天我还不需要深入函数但这个区别我提前记下来了因为很多新手几个月后还在混淆这两个概念。2.3 变量不是盒子是标签关于变量我第二天最大的认知改变是从“盒子模型”到“标签模型”。很多教程会把变量比喻成盒子a 1就像是把数字1放进一个叫a的盒子里。但我看到一个更准确的说法Python里的变量更像是贴在对象上的标签。a 1是把数字1这个对象创建出来然后把标签a贴上去a 2不是把盒子里面的1改成2而是重新创建了一个2对象把标签a撕下来贴到2上面。这个区别最直接的表现就是多个变量指向同一个对象时的情况a [1, 2, 3] b a b.append(4) print(a)如果你以为b a是把a的“内容”复制给b那你会觉得输出应该是[1, 2, 3]。但实际输出是[1, 2, 3, 4]因为b和a贴的是同一个列表对象改b就是改那个对象本身。这个知识点对初学者来说有点超前但第二天提前有个印象后面学列表和字典的时候就不会那么懵。2.4 变量命名的讲究第二天我还注意到了一个细节变量名不能随便起。不能以数字开头比如2name 小明会直接报语法错误。不能使用Python的保留字比如if、for、while、class这些都有特殊含义不能当变量名。大小写敏感Name和name是两个不同的变量。中文变量名虽然技术上能用但我不太推荐除非做教学演示。我有一次写代码给一个临时变量起名叫sum结果程序运行到后面某些逻辑时行为很怪异排查了半天发现sum是Python的内置函数被我覆盖掉了。从那以后我给自己定了个规矩变量名尽量用英文小写加下划线如user_name、total_count能明显减少这类不必要的麻烦。3. 字符串和数字打架第二天最典型的报错现场3.1 一个百试百灵的小练习BMI计算器第二天下午我把早上学的变量、字符串、输入输出整合到一起写了一个简单的BMI计算器。这个练习很老套但确实有用因为它会强迫你处理“输入的数据类型”这个问题。需求很简单输入身高米和体重公斤输出BMI值和简单的判断。height input(请输入身高米) weight input(请输入体重公斤) bmi weight / (height * height) print(你的BMI是, bmi)一运行报错TypeError: unsupported operand type(s) for /: str and str原因正是我前面提到的问题input()返回的永远是字符串。哪怕你输入的是1.75在Python看来它也是字符串1.75不是数值1.75。字符串不能参与除法所以报错。这个报错在第二天就遇到了其实是好事。它让我真正理解了“为什么需要类型转换”。后来看不少教程说“Python是动态类型语言”这句话听起来很高端但落到实际就是变量可以装任意类型但运算符对类型有要求类型不对就要转换。3.2 类型转换的常用姿势改法很简单用float()把字符串转成小数height float(input(请输入身高米)) weight float(input(请输入体重公斤)) bmi weight / (height * height) print(你的BMI是, round(bmi, 2))Python里常用的类型转换函数就这么几个int(x)转成整数比如int(123)得到123。float(x)转成浮点数比如float(1.75)得到1.75。str(x)转成字符串比如str(18)得到18。bool(x)转成布尔值这个稍后学条件判断时会反复用到。有几个转换时的坑我觉得值得提前列出来int(1.75)会报错。字符串里是小数格式直接转整数是不行的得先float(1.75)再int(...)或者直接int(float(1.75))。我当时试了int(1.75)报错ValueError: invalid literal for int() with base 10: 1.75这个报错信息其实已经把原因说得很清楚但新手第一眼往往看不懂。int(abc)也会报错因为字符串内容不是数字。float(1.75abc)同样报错Python不允许这种混合格式直接转。还有一种情况输入了空字符串直接回车也会报错。所以更稳妥的写法是加个条件判断不过第二天我还没系统学if就先记下这个问题了。3.3 除法的另一个坑/ 和 // 的区别第二天写BMI计算器时还发现了一个有趣的细节Python里的除法其实分好几种。/是普通除法结果是浮点数。比如5 / 2结果是2.5。//是整数除法地板除结果向下取整。比如5 // 2结果是2。%是取余数比如5 % 2结果是1。**是幂运算比如2 ** 3结果是8。很多新手会在这上面卡住为什么有时候计算结果是1.0有时候是1其实就是运算符选错了。比如10 / 2的结果是5.0虽然数值上等于5但类型是浮点数。有一次我想写个程序判断一个数是不是偶数写的是num % 2 0。这个写法很优雅但后来我又遇到一个需求想取一个两位数的十位比如37的十位是3。做法是37 // 10得到3个位是37 % 10得到7。别看这两行代码简单它能让你彻底理解//和%的实际用途。3.4 一个顺手写的温度转换小工具为了巩固类型转换我还写了一个摄氏度和华氏度的互相转换脚本。这个比BMI还要简单但能练到input、float、print的综合使用celsius float(input(请输入摄氏度)) fahrenheit celsius * 9 / 5 32 print(f{celsius}摄氏度 {fahrenheit}华氏度)输出示例请输入摄氏度25 25.0摄氏度 77.0华氏度这段代码里用了f{celsius}...这种格式化字符串的写法是Python 3.6以后才有的 f-string 语法。第二天能接触到这个算是意外收获。它的优点是简洁、直观而且不用管类型转换直接往里填数值就行。后来我写脚本时f-string成了我最常用的输出方式。4. 与其干背语法不如写两个能跑起来的小东西4.1 三行代码画个爱心学了几天基础语法如果只会在终端里打印文字很快就会觉得无聊。第二天我做了一个调整每学一个知识点就强迫自己写一个“能看得见效果”的小程序哪怕是三行代码也比单纯抄例子有成就感得多。比如爱心代码用最朴素的print就能画出来网上流传的很多爱心代码其实只是打印了一堆符号print(\n.join([.join([(♥ if ((x*0.05)**2(y*0.1)**2-1)**3-(x*0.05)**2*(y*0.1)**30 else ) for x in range(-30,30)]) for y in range(15,-15,-1)]))这段代码第一天我看见跟看天书一样第二天再来看能大概理解它是在坐标系里遍历每个点判断点是否落在爱心公式内部。虽然暂时不打算背这种代码但它至少让我知道了同一句print可以写出花来。这比天天print(hello)有意思。4.2 猜数字第二天就能完成的“小游戏”当天晚上我给自己布置了一个稍微有点挑战的任务写一个猜数字游戏。规则是程序随机生成一个1到100之间的整数用户输入数字程序提示“猜大了”或者“猜小了”直到猜中为止。这个任务会用到三个第二天刚接触的知识点随机数、条件判断、循环。我当时还没系统学for但大致知道while是“当条件成立时一直循环”于是硬着头皮写了出来import random answer random.randint(1, 100) guess 0 count 0 while guess ! answer: guess int(input(请输入你猜的数字1-100)) count count 1 if guess answer: print(猜大了) elif guess answer: print(猜小了) else: print(f恭喜你猜了{count}次终于猜中了)运行之后我第一次体验到了“自己写的小程序能一直陪我玩”的感觉。虽然逻辑很简单但它包含了随机数生成、循环控制、条件分支、累加计数、f-string输出几乎把第二天学的东西全用上了。后来我还给这个游戏加了一点小功能限制最多猜7次猜不中就提示正确答案。加了个if count 7的判断程序退出。这里有个容易被忽略的小知识点random.randint(1, 100)是闭区间也就是可能生成1和100两个端点值。我之前以为跟range一样是“含左不含右”实际试了下生成100次发现100确实出现过才明白这个函数的边界语义跟range不一样。这种细微的区别写代码时不会有人专门提醒你只有自己动手才会踩到。4.3 为什么我推荐“小游戏驱动学习”第二天最大的感受是纯粹的语法学习效率其实很低。如果你对着教程抄一遍“for循环有三种写法”大概率第二天就忘了。但如果你是在写“猜数字”时用到了while你可能很久都忘不了因为你记得“当时我要判断用户输入是不是正确需要循环让用户重新输入”。我给自己定了个小目标每学一个新知识点就把它塞进一个小项目里。学while就写猜数字学random就写随机抽签学字符串操作就写个简易密码校验脚本。哪怕每个项目只有十行代码也比不动手强。这背后的逻辑是知识点是散落的项目是串起这些散落点的一条线。有了项目场景你的大脑才更容易记住“什么情况下该用什么语法”。5. 第二天我调整了学习方式说几条实在建议5.1 IDE到底选VS Code还是PyCharm第二天我花了不少时间在编辑器上。我第一天用的是VS Code第二天听人推荐PyCharm又去装了个Community版试用了一下。我的感受是VS Code启动快插件丰富轻量适合写小脚本和日常练习。但Python环境配置需要自己动手尤其是“解释器选择”和“终端环境路径”新手容易搞混。PyCharm Community对Python项目开箱即用自动帮你识别解释器运行按钮一目了然非常适合专注学语法的新手。缺点是启动偏慢界面信息多。我的建议是如果只是学语法、写几十行的练习VS Code完全够用如果打算系统学Python做项目可以两样都试一下选自己舒服的。不用纠结“哪个更好”真正重要的是你能不能快速进入“写代码”的状态。5.2 报错不可怕可怕的是不读报错第二天我大概遇到了十几次报错每次报错都让我烦躁但到了晚上我逐渐摸索出一个笨办法把报错信息的最后一行读一遍。把关键词复制到搜索引擎里搜。搜出来的结果不一定要全看先看前两三条重点找同一个报错信息。比如TypeError: can only concatenate str (not int) to str搜索关键词“Python can only concatenate str not int”很快就能找到解释。这个报错的意思是“字符串只能和字符串拼接不能和整数拼接”解决的方法就是做类型转换。后来我意识到一个更重要的事报错信息其实是Python在告诉你它想要什么。很多报错英文虽然长但其实核心就是最后那一句。新手最容易犯的毛病是看到红色报错就慌直接截图发群里问连报错信息都没读完。其实90%的问题只要读完最后一行自己就能猜到大概方向。5.3 手敲代码比复制粘贴管用得多第二天学习时我有过一个很明显的对比有一段爱心代码我先是复制过来直接运行觉得很酷但过了一天再让我写完全写不出来。后来我逼着自己一个字一个字手动敲了一遍虽然敲得很慢还经常打错括号但敲完那一次之后我对join、列表推导式、坐标循环这些概念的理解明显加深了。所以我现在更推荐新手“照着代码敲”而不是复制粘贴。复制粘贴只能得到运行结果手动敲才能得到“手感”。敲错几次、语法报错几次反而会让你记住正确的写法。5.4 学习节奏别贪多每天三小时足够第二天我还犯过一个贪多的毛病。上午想学变量下午想看爬虫晚上又想研究数据分析结果到了深夜哪样都只沾了个皮毛。后来我给自己定了一个更适合实际情况的节奏每天只学一个核心知识点比如“今天就是字符串和类型转换”。用一个小项目验证这个知识点比如“写一个温度转换器”。把今天遇到的报错和解决思路记录到自己的笔记里。节奏慢下来之后心里反而踏实了。第二天学到的内容比第一天多得多不是因为我学得快而是因为我不再急着“三天入门、七天精通”开始老老实实按自己的进度一点点磨。回头看第二天的学习经历最值得记录的其实不是具体语法而是那些“哦原来是这么回事”的瞬间——比如环境变量、比如input()返回字符串、比如二分查找的猜数字策略。如果你也在学Python的第二天希望这份记录能让你少走一点弯路但我也建议你保留一点“自己踩坑”的空间。有些坑只有自己踩过才算真的学会。