ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

自学编程第八天:白纸复盘变量内存,手写函数避坑指南

自学编程第八天:白纸复盘变量内存,手写函数避坑指南 这是记录学习计算机的第八天。今天没有往后面赶新进度反而干了一件看起来挺“吃亏”的事把前七天的知识从头到尾复盘了一遍步骤简单到有点寒酸——一张白纸一支笔不翻笔记不查资料。起因是昨晚学函数的时候视频里的老师讲得清清楚楚弹幕也说“讲得真好”我也觉得自己完全听懂了可今天早上想独立写一个带参数的函数手放在键盘上愣是不知道第一行该写什么。这种“看视频全会关视频全废”的体验大概是每个自学计算机的人都绕不过去的一课我只是恰好撞在了第八天。零基础自学本来就是一个不断打破幻觉的过程。前七天我学得挺爽每天都往笔记里塞新名词变量、字符串、循环、列表、字典感觉进度飞快。直到第八天的“白纸复现”才把我打回原形——也正是在那一刻我才摸到了一点真正入门的门槛。1. 第八天我决定先停下来把地基重新踩一遍1.1 前七天我实际学到的比我以为的少很多先把我前七天的真实进度摊开免得有人觉得我在凡尔赛。第一天花了半天搞懂计算机的基本组成CPU、内存、硬盘、输入输出设备顺便被二进制和十六进制折腾得够呛。第二天安装了 Python知道了什么叫交互式环境然后打出人生第一行print(hello world)还截图发了朋友圈。第三天学变量和算术运算知道a 5就是把 5 存进去。第四天学字符串搞明白了拼接和 f-string。第五天学if/else写了一个只会判断一次的猜数字雏形。第六天学while循环终于让猜数字能重复猜下去了。第七天学列表和字典知道了append和for循环可以用来遍历数据。这样看下来进度其实不算慢对不对我当时也这么觉得。但问题恰恰藏在这里我学到的是一个个孤立的知识点它们在我脑子里像一堆没有装修好的毛坯房单独看每一间都能进去但要从这间走到那间中间全是断头路。比如我知道列表有append方法可真写程序时根本不知道该在什么时候用列表什么时候用字典我知道while的语法长什么样但写猜数字时反复纠结“到底先判断还是先输入”才算正确。1.2 一张A4纸暴露出来的知识断点我今天上午的复盘方法特别土但效果出奇好拿一张空白A4纸中间写下“第一周学过的所有东西”然后开始往外面默写。能写出来的内容包括print、变量赋值、if/else基本写法、while循环、for循环、append、int()和str()类型转换。写到这里笔就开始慢了。字符串方法我只想起replacesplit和upper是强撑着写出来的列表的remove、insert、count只能认个脸字典的items()和get()更是直接空白至于函数我只知道“用def定义”参数和返回值的区别完全说不清。我把复盘结果整理成了下面这个表给自己一个不留情面的交代知识点我的真实状态print、变量、算术运算能独立写比较熟练字符串基础与拼接能独立写但方法记忆模糊if/else、while循环能写简单场景一复杂就乱列表基础与遍历只会append和for其余靠猜字典基础只记得键值对方法基本不会函数定义与调用看得懂写不出这张表彻底治好了我的“进度焦虑”。看视频和抄代码的时候我根本意识不到自己有这么多盲区因为眼睛会自动忽略不熟的部分心里只记着“运行成功了”的爽感。但白纸复现没有任何反馈不会骗人。1.3 为什么“看懂”压根不算“会写”这次复盘还让我想明白一件事我以前很多“会了”其实记住的不是逻辑而是画面。视频里老师写一行我也写一行屏幕上的光标走到哪我的手就跟到哪。等到合上视频我脑子里没有“这段程序怎么从需求一步步变成代码”的路径只有“刚才好像出现过一串五颜六色的单词”的画面。这就好比看别人玩拼图看的时候觉得每一块都认识轮到自己拼连从哪块开始都不知道。所以我给第八天定的核心任务不是继续堆新知识而是把已经见过面的知识点从“眼熟”变成“手熟”。这也是我想给同样在自学的人提的第一个醒当你觉得某个东西“看懂了”的时候先别急着往下一个知识点冲拿白纸默写一遍或者直接关掉教程写代码能写出来才算真正过了一道门槛。2. 真正把“变量”和“内存”搞懂的那一瞬间2.1 变量不是盒子更像贴在数据上的标签前七天我一直背一句教科书定义变量是程序运行中用来存储数据的容器。听起来好像没毛病但今天我在复盘时自己把自己问住了如果变量是盒子那b a到底是什么意思是把 a 的盒子复制了一个给 b还是把盒子里面的东西倒进另一个盒子我曾经试着用“盒子理论”解释下面这段代码结果怎么解释都别扭a [1, 2, 3] b a b.append(4) print(a) # 想当然以为还是 [1, 2, 3]结果变成了 [1, 2, 3, 4]如果 a 和 b 是两个独立的盒子b 往自己盒子里塞东西a 不应该受影响。但程序运行结果告诉我a 也变了。这说明我理解的“变量”从根上就错了。真正让我开窍的是用“门牌号”和“房间”来理解数据在内存里有自己独立的房间一个房间有唯一的地址变量名不是房间本身只是贴在房间门口的门牌号。a [1, 2, 3]的意思是创建一个列表对象放进某个房间然后把“a”这个门牌号挂上去。b a不是复制房间而是拿第二张门牌号挂到同一个房间门口。所以通过 b 往房间里放东西a 自然也能看到。到这一步我之前那些困惑全部有了答案列表是可变对象所以b a之后修改 b等于在同一个房间动了手整数、字符串是不可变对象看起来“变了”实际上是门牌号被摘下来挂到了另一个新房间旧房间里那个对象根本没动过。2.2 用 id() 和 is 亲手做了个小实验光在脑子里想还不够我下午打开编辑器把书本上的理论变成了自己亲手跑出来的结果。用到的核心工具是id()函数它返回数据在内存里的地址你可以把它理解成“房间门牌号”。我做了两组实验。第一组验证“同一个房间”a [1, 2, 3] b a print(id(a)) # 2165031641728 print(id(b)) # 2165031641728 print(a is b) # True b.append(4) print(a) # [1, 2, 3, 4]id一样is是True说明 a 和 b 指的就是同一个对象。这个结果一点都不神秘它只是把“引用关系”摆到了明面上。第二组验证“换房间”c [1, 2, 3] d a d d [5] print(id(a)) # 和上面一样 print(id(d)) # 一个新的地址 print(a) # [1, 2, 3, 4] print(d) # [1, 2, 3, 4, 5]这里我用了拼接。结果很有意思a 没有变成带 5 的列表d 却多了一个 5。因为d [5]是先创建了一个全新的列表对象再把 d 这个标签贴到了新房间门口旧房间也就是 a 所在的位置完全没被动过。最后我还试了不可变对象的场景x 10 y x x x 1 print(x) # 11 print(y) # 10x 虽然变了但 y 依然停在 10 上因为x 1产生了一个新的整数对象x 被重新贴到新对象上y 还留在原来的 10 那里。2.3 这个理解为什么值回票价如果只是为了一道输出题我完全可以跳过这个知识点。但有句老话说得对基础不牢地动山摇。把变量和内存地址的关系搞清楚之后后面很多东西突然就顺了。比如函数传参。我还没正式学函数但今天已经能预见如果函数接收一个列表参数并且在函数里直接修改它外面那个列表也会跟着变如果函数里对参数重新赋值外面的变量不会受影响。这个东西如果靠死记硬背翻车只是时间问题但理解了“标签与房间”之后它本来就是顺理成章的事。学习最怕的就是“昏昏暗暗的知道”。今天花了一个下午把变量这一个词彻底弄明白我觉得比糊里糊涂看完三节新视频划算得多。3. 今天踩过的三个坑每一个都值得写进新手的避坑手册3.1 安装完Python命令行却说“不是内部或外部命令”这个坑说出去有点丢人但我猜踩过的人绝对不少。今天下午我想在命令行里跑一个脚本刚输入pythonWindows 直接甩回来一句python 不是内部或外部命令也不是可运行的程序或批处理文件。我第一反应是“Python 是不是没装上”但打开开始菜单Python 明明就在那里。后来才想起来好几天前安装的时候安装向导第一步有一个Add Python to PATH的勾选我当时觉得“PATH 是什么东西先不管了”一路点下一步。这个选项其实就是把python.exe所在的目录写进系统环境变量这样命令行在任意位置输入python系统都能顺着 PATH 里的目录列表找到这个程序。我没勾选等于让系统“找不到路”。解决步骤我重新走了一遍记录在这里希望有人能少走弯路先确认 Python 真的装上了。打开开始菜单找到 Python 文件夹看它到底装在哪。常见路径是C:\Users\你的用户名\AppData\Local\Programs\Python\Python312\。复制python.exe所在的那一层目录路径。注意是包含 python.exe 的那一层不是 Python 总目录。右键“此电脑” → 属性 → 高级系统设置 → 环境变量。在用户变量里找到Path这一行双击打开点“新建”把刚才复制的路径粘贴进去点确定。重新打开一个全新的命令行窗口旧窗口不会自动刷新 PATH输python --version看到版本号就说明通了。这里还有一个进阶提醒如果电脑里装了多个版本的 Python或者以后用包管理器装过其他工具PATH 里会出现多条路径。Windows 是从前往后找的排在前面的优先执行。万一输入python进的是旧版本可以用py -3这种启动器明确指定版本。3.2 用记事本写的代码运行起来全是乱码下午写代码的时候我图省事用 Windows 自带的记事本存了一个测试脚本里面有一行中文注释。保存的时候我看都没看直接点保存。运行的一瞬间报错信息差点让我以为是电脑坏了SyntaxError: Non-UTF-8 code starting with \xd6 in file test.py on line 1, but no encoding declared这个坑的根源是编码格式对不上。Windows 记事本在中文系统下默认用 GBK也叫 ANSI保存文件而 Python 3 默认把.py文件当 UTF-8 编码来读。两边对不上解释器一读到中文就崩了。解决办法有两个。第一个是治本的写代码不要用记事本换一个现代编辑器比如 VS Code 或 PyCharm把右下角的编码改成 UTF-8。第二个是应急的如果手头只有记事本保存的时候在“编码”下拉框里手动选 UTF-8不要在“ANSI”上待着。另外给一个进阶经验以后读文本文件时只要内容里可能有中文我都会在open()里显式指定编码比如open(data.txt, encodingutf-8)。不指定的话Windows 上可能会按 GBK 去打开 UTF-8 的文件又会来一场UnicodeDecodeError。编码这个东西新手期最容易忽略一旦遇到务必把“保存编码”和“读取编码”当成一对儿来排查。3.3 缩进和全角符号新手最隐蔽的敌人第三个坑我今天踩了两回也是最让我抓狂的。有一次运行时报了IndentationError: unexpected indent我盯着代码看了半天没看出来哪儿缩进有问题。最后把编辑器里的空白字符显示打开才发现某一行前面是 Tab其他行是空格。在 Python 里缩进决定代码块的层次Tab 和空格混用会让解释器分不清你到底属于哪个块。另一次更鬼畜代码看起来完全正常但一运行就报语法错误。我逐行检查最后发现是输入法在作怪。我打中文注释的时候顺手打了个中文分号和中文引号那个逗号也变成了全角逗号。Python 只认英文半角符号全角符号会让它直接蒙圈。排查这类问题有一个高效技巧在编辑器里开启“渲染空白字符”功能VS Code 的命令面板里搜Toggle Render Whitespace。打开之后空格会变成小圆点Tab 会变成小箭头一眼就能看出缩进到底是不是统一的。另外写完代码后全选用命令面板里的“Convert Indentation to Spaces”把 Tab 统一换成四个空格能省掉后面大量的奇怪报错。我把这三个坑总结成一句话装环境时认真看勾选项写代码时用现代编辑器代码里的标点必须全英文半角。这三条每一条都是过来人用报错换来的。4. 从“抄代码”到“复现代码”我换了一种效率高得多的学法4.1 边看视频边敲代码本质上是在自我感动前七天我的学习方式特别一致打开视频老师说一句我敲一句整个流程行云流水。代码运行成功的那一刻弹幕里飘过“老师讲得真好”我也跟着觉得“我真棒”。但今天上午的复盘把我这层滤镜撕碎了——我连一个最简单的函数都写不出来。冷静下来分析问题出在“抄写”上。抄写的时候手指很忙大脑却是放空的。眼睛看到老师敲了什么手就把它复现出来整个过程不需要任何规划和判断。它带来的成就感是虚假的因为我根本没有经历“看到任务 → 想方案 → 动手写 → 出错 → 修正”的完整闭环。举个最通俗的例子在岸上跟着教练做游泳动作每个动作都能比划出来但一下水还是会呛。写代码也是一样真正难的从来不是那几行语法而是“看到需求之后怎么把它拆成一行行代码”的过程。4.2 新的学习流程关掉视频凭记忆复现下午我把自己的学习方法整体切换成了“复现式”学习流程是这样的看一节视频只看 15 到 20 分钟不贪多。关掉视频在纸上写下这一节要解决的核心任务就一句话。不参考任何代码先写伪代码把逻辑捋顺。打开编辑器凭记忆写真实代码遇到想不起来的语法先空着。卡壳超过 5 分钟才允许回头看视频或者翻文档但只准看一眼提示然后继续关掉自己写。全部写完并运行通过后再和参考实现对比记录差异点想想为什么他那么写。这套流程最大的变化是把“输入式学习”变成“输出式学习”。写不出来的时候哪里不会立刻就会暴露得清清楚楚而不是被视频的流畅节奏一带而过。4.3 实战用函数重写猜数字游戏晚上我没学新课把第一周的猜数字游戏用函数重写了一遍。需求一句话程序随机生成一个 1 到 100 的整数玩家最多猜 10 次每次提示大了或者小了最终输出结果。我先在纸上写伪代码导入随机数模块 生成答案 循环最多10次 获取玩家输入并转成整数 判断输入与答案的关系 大了打印“大了”小了打印“小了” 猜中结束程序 循环结束还没猜中公布正确答案伪代码写得很顺但真正敲代码的时候啪啪打脸。第一个错误是忘了把input()的结果转成整数字符串和整数一比较直接TypeError。第二个错误是循环次数处理得不对我以为从 0 开始循环 10 次就够了实际上玩家只获得了 9 次机会因为第 10 次循环进去之后要马上判断最后一次输入根本没来得及。第三个错误是第一次用记事本跑中文输出又踩了一遍编码坑。改到最后代码长这样import random def guess_game(max_tries10): answer random.randint(1, 100) for i in range(max_tries): num int(input(请猜一个1-100的整数)) if num answer: print(大了) elif num answer: print(小了) else: print(恭喜猜中了) return print(f次数用完了正确答案是{answer}) guess_game()这段代码放在任何老手眼里都是入门级但对我来说意义完全不同。那几个报错不是视频里的不是书本上的是我亲手制造又亲手修掉的。特别是那个循环次数错位的错误如果没有亲手踩一遍我可能永远只会在视频里看到“注意边界条件”这句轻飘飘的提醒。4.4 用“费曼式复述”检验理解学完变量和内存之后我照着网上的建议做了一件很羞耻但很有用的事把“列表和字典的区别”用自己的话讲给一个完全不懂编程的朋友听而且用手机录了音。不录不知道一录吓一跳。我以为自己已经理解了结果一开口就东拉西扯讲了“列表是按顺序排队、字典是键值对”但又说不清到底什么时候该用哪个。录音里全是“就是那个……你懂吧”这样的废话对方当然不懂。我关掉录音老老实实回去重新整理列表是按顺序排好的一排抽屉抽屉上有编号你可以通过下标快速取第几个。适合存放“同一类东西的集合”比如城市列表、学生名单。字典是不按顺序排列的抽屉柜每个抽屉都有名字你可以直接按名字找内容。适合存放“有结构的信息”比如一个人的姓名、年龄、城市。选择原则很简单要按顺序处理数据用列表要用某个名字快速找值用字典。整理完之后我又录了一遍这次能比较流畅地说清楚了。这个过程让我明白能向别人讲清楚才是真正学会讲不清楚说明脑子里只有一个模糊的轮廓。如果你想检验自己的学习效果随便找个没基础的人讲一次你当天学的东西你会比考十道题更清楚自己几斤几两。5. 自学第八天的真实节奏反思与明日计划5.1 第八天为什么最容易说放弃这两天我一直在想一个问题为什么网上那么多自学记录大多断更在一周左右今天自己学到第八天多少有点体会。前七天的正反馈来得太容易了。每多学一个知识点都像打游戏捡了一个新道具哪怕是print换个写法都能自我感动半天。但到了第八天新鲜感明显消退函数、作用域、内存这些抽象概念开始真正考验脑力写小项目又发现自己到处报错于是很容易产生一个念头“我是不是根本没有天赋”我想说的是这大概率不是天赋问题而是学习阶段切换的问题。第一周是在“认识名词”就像刚进一家餐厅看菜单每道菜名都很新鲜第二周开始上菜了你得真正用刀叉吃了这时候觉得慢、觉得笨才是正常的。一个比较有效的应对办法是把目标从“我今天要学会多少”改成“我今天比昨天多写对了几行代码”。只要还在出错、还在修错、还在往前走就没有白学。5.2 我给自己立的三条学习纪律基于今天的复盘和踩坑我给自己立了三条纪律准备从第九天强制执行。第一条每天必须产出一段能独立运行的代码哪怕只有十行。这条纪律是为了切断“我觉得我懂了”的幻觉代码能跑才算数。第二条每个新概念都必须用自己的话讲一遍讲不出来就回去重学。这条纪律执行起来最费时间但效果也最好。笔记不要再抄教程原文要改成“今天学的这个东西我能举出什么例子”。第三条遇到 bug 先记录现象和解决过程同一个坑绝对不踩第二次。我今天已经建了一个“报错收集表”以后每次遇到问题就往里填一列报错信息、发生场景、根因、解决办法。过几个月回头看这张表会比任何学习笔记都有价值。5.3 明天的安排函数、小项目和第九天的记录明天我给自己定的学习任务不多就三件事。第一正式学函数把参数、返回值、局部变量和全局变量搞清楚。今天对“标签与房间”的理解刚好可以拿来验证函数传参看看可变对象和不可变对象在函数里到底怎么表现。第二做一个“备忘清单”小项目把列表、字典、函数和文件读写串在一起。项目本身不复杂但能把过去八天学的东西第一次真正用在一个完整的应用里。我预感会卡住但按今天的经验卡住的地方才是长本事的地方。第三继续写“记录学习计算机的第九天”把这个连载坚持下去。把学习过程公开相当于给自己找了一个无形的监督者。每多想一次“今天还没写日记”就会多打开编辑器写一段代码。第八天最大的收获不是我背下来一个新的语法而是终于从“看视频”切换到了“动手写”。如果屏幕前的你也在自学计算机正处在某个“第八天”的徘徊期我想说卡住很正常抄不来也别慌今天学不会的函数可以留到明天明天再不会就把它拆成更小的例子反复拆。学习进度慢一点真的没关系关键是自己亲手写出来那行代码时心里那份踏实感是刷多少集教学视频都换不来的。
返回列表