Python入门第五次作业复盘:从类型转换到数据聚合与打包全解析

发布时间:2026/9/10 9:18:40
Python入门第五次作业复盘:从类型转换到数据聚合与打包全解析 作为一个带了三轮 Python 入门班的人每次批到第五次作业我都有点感慨前四次作业大家虽然也写但基本都是对着知识点“点对点”完成任务。到了第五次我把知识点串成了一个小型项目闭环结果提交上来的代码水平瞬间分层了——有人用四五个函数把任务拆得干干净净有人还卡在int()和str()的类型转换上报错。这篇文章就是这一次作业的完整复盘从设计思路、任务拆解到环境配置、报错排查再到最后的打包和趣味扩展一次性说清楚。写得比较细适合正在学 Python 的初学者按步骤跟着做也适合带新人的朋友拿去当教学参考。1. 第五次作业我到底布置了什么一个“小综合”的设计思路1.1 前四次作业都在打什么底子很多自学者会有一个误区学 Python 就是今天学个print明天学个for后天学个list每个月都在学“基础语法”却一直不知道这些语法堆在一起能干嘛。我留作业的时候就在想这个问题。前四次作业我是这么安排的第一次输入输出 变量写一个简单的姓名年龄问答程序。第二次if分支 while循环写一个猜数字游戏循环条件写不对的人扎堆。第三次列表、字典、元组的增删改查做一个通讯录的数据管理小程序。第四次函数 文件读写把通讯录保存到文本文件里再从文件读回来。看到这里你应该明白了前四次是在逐个教“积木”怎么用。到第五次我要求大家把这些积木搭起来做一个完整的、有输入有输出有中间处理的小项目。这一步跨过去Python 基本就算真正入门了。1.2 这次作业的核心任务清单第五次作业我总共布置了三个必做任务和一个附加任务目标是模拟一个真实开发的完整链条数据获取 → 数据清洗 → 统计分析 → 结果输出。任务卡大概是这样的类型处理与函数封装写一个函数接收用户输入的两个字符串将它们转换为数值计算第一个数除以第二个数的绝对值同时要处理各种不合法输入空字符串、全角数字、非数字内容等。这题是考验对类型转换和异常处理的掌握。数据聚合统计给出一段模拟的商品销售记录列表套字典统计每个商品类别售出的总数量和总金额输出结果要求排序。要求至少用两种方式实现手写循环完成分组聚合再用 pandas 的groupby验证结果一致。简单爬虫用requests请求一个公开的 JSON 接口我给的是一个公开的待办事项数据接口统计已完成和未完成的数量把结果保存成 CSV 文件。附加题用 matplotlib 画一张能够反映任务二或任务三结果的图表再另外做一个用 PyInstaller 打包成 exe 的挑战让没有 Python 环境的同学也能运行你的程序。表面上看这四道题考的是不同的知识点实际上我只想练三件事函数抽象能力能不能把逻辑封装成可复用模块、数据组织能力面对一堆原始数据能不能整理成想要的结构、工具链熟练度pip 装包、IDE 配置、文件读写、打包发布。这三件事恰恰是很多自学 Python 大半年的人最欠缺的。2. 动工之前先把环境关过了安装、多版本、IDE、pip 一条龙2.1 多个 Python 版本并存为什么我建议用虚拟环境批作业的时候有好几个学员卡在了“装了两个 Python 不知道用哪个”的问题上。最常见的场景是电脑里既装了 Python 3.8 又装了 3.11命令行敲python输出的是 3.8但 PyCharm 里解释器选的却是 3.11结果用 pip 装好的包在 IDE 里import就是报ModuleNotFoundError。这不是 Python 的问题是解释器和包管理器没对应上。Windows 下如果安装了多个版本从官方安装包安装时一般会附带py这个启动器你可以用这种方式查看py -0它会列出所有已安装的 Python 版本。运行脚本时可以用py -3.8 script.py py -3.11 script.py安装包时对应使用py -3.11 -m pip install requests但更推荐的做法不是手动区分版本号而是在具体项目目录下创建虚拟环境。虚拟环境相当于给这个项目单独圈了一个“独立房间”里面装什么包都不会污染全局环境也不会出现“版本串门”的问题。我的习惯是每个作业项目都建一个# 在项目目录下执行 py -3.11 -m venv venv # 激活Windows venv\Scripts\activate # 激活macOS/Linux source venv/bin/activate激活之后命令行前面会出现一个(venv)前缀这时候再执行pip install装的所有包都只属于这个项目。下次再遇到“为什么我明明装了 pandas 还是 import 不了”这类问题先确认一件事你当前用的解释器和你安装包用的是不是同一个环境。这个排查思路能解决 80% 的 import 报错。2.2 PyCharm 和 VSCode 怎么选我的实际感受在作业交流群里每次都会有人问“到底是 PyCharm 好还是 VSCode 好”。我自己的答案很简单这个阶段选你装了之后能立刻开始写代码的那个。PyCharm 社区版是免费的对 Python 的支持最完整。新建项目时它会自动帮你创建虚拟环境和基础目录CtrlShiftF10直接运行脚本报错信息带超链接点一下就能跳到源码行。对前几次写作业来说这些功能省掉了很多“配置环境”的心智负担。如果你是零基础我的建议是用 PyCharm。VSCode 本身是个通用编辑器Python 支持靠插件。好处是轻量、启动快、可自定义程度高坏处是你需要自己理解“解释器路径”“launch.json”“settings.json”这些概念。VSCode 里配置 Python 的关键步骤其实不复杂装 Python 扩展、CtrlShiftP打开命令面板、选择 “Python: Select Interpreter”、指定你的虚拟环境路径。但这一步对小白来说就是个门槛我见过不少人在这个环节卡了半小时。其实环境变量也是一个常被忽略的点。Windows 下如果在安装时没有勾选 “Add Python to PATH”那么命令行里敲python就会提示找不到命令。解决办法是到系统环境变量的 PATH 中手动添加C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\以及同目录下的Scripts文件夹。路径里的版本号根据你实际安装的来写Scripts目录是放 pip、pyinstaller 等命令行工具的地方漏掉它会导致“pip 安装成功了但命令行找不到这个命令”。2.3 import 报错和“缺失的包”一套通用解法这次作业里因为要额外装requests、pandas、matplotlib、openpyxl所以“缺包”问题成了第一大拦路虎。最常见的报错长这样ModuleNotFoundError: No module named requests我看到有人遇到这种报错之后的第一反应是去网上搜“如何安装 requests”找到了三条不同的命令挨个试还是报错。原因通常是命令行里用的 pip 和当前编辑器用的 Python 不是同一个环境的。所以我的建议是以后遇到任何“缺包”的问题先搞明白三件事当前代码运行时用的是哪个 Python 解释器在 PyCharm 右下角可以直接看到VSCode 里看左下角状态栏这个解释器对应的 pip 是哪个在代码同级目录下直接使用系统解释器的路径 -m pip是最稳的如果项目有虚拟环境是否已经激活安装时顺手用清华或阿里镜像速度会快很多pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple如果你在别的教程里看到类似“请安装缺失的包以使用此工作流请在 Python 环境中运行 pip install ... ”的提示本质上也是同一件事按上面三步排查找到缺的包名用正确的解释器安装即可。3. 第一关就卡住大半人类型转换和内置函数的“隐形坑”3.1 int()、float()、str() 的转换陷阱任务一看起来很简单但批改时发现能一次性写完且不报错的人真的不多。核心原因在于input()返回的永远是字符串而字符串转数值时有一大堆边角情况。最容易踩的坑有这几个int(3.14)会直接抛ValueError因为int()不接受带小数点的字符串。float(3.14)可以正常转换但float(1,000)不行因为逗号不是数字一部分。int( 42 )合法因为字符串前后的空格会被忽略但int(42.0)不合法。全角数字比如“”转 int 依然会报错除非先用unicodedata.normalize做标准化。bool(False)的结果是True因为非空字符串永远是 True。我让学员实现的时候要求把“用户输入”这个过程单独抽象出来做成一个函数返回能用的数值如果实在不能转就返回None。这样做的好处是主逻辑和输入逻辑解耦了以后想在命令行里测试也好想换成一个图形界面也好函数不用改。可以按照这个思路来写def safe_float(value: str): 把用户输入安全地转成 float失败返回 None if value is None: return None text value.strip() if text : return None try: return float(text) except ValueError: return None def safe_abs_divide(a: str, b: str): 计算 |a / b|b 为零或任一输入非法时返回 None num_a safe_float(a) num_b safe_float(b) if num_a is None or num_b is None: return None if num_b 0: return None return abs(num_a / num_b)这里用到的strip()是新手比较容易忽略的方法——用户输入“ 3.14 ”如果不做处理直接float()虽然 Python 也能处理后面加空格的情况但前面带空格加换行符时在某些场景下会出错。养成先strip()再转换的习惯是这些年在写各种输入处理程序时最值得记住的一点。另外abs()这个内置函数也要特别注意它的“适用范围”abs()只对数值类型和实现了__abs__的对象有意义传入字符串abs(a)会抛TypeError。不少初学者会把“绝对值”理解成“去掉符号”然后试图对字符串操作这是概念上的混淆。这道作业题里把abs()和类型转换放在一起考就是为了让大家注意到这个边界。3.2 一个完整的参考实现一个参考实现大致是def main(): a input(请输入第一个数字) b input(请输入第二个数字) result safe_abs_divide(a, b) if result is None: print(输入不合法或除数为零无法计算。) else: print(f|a / b| {result})运行效果如下请输入第一个数字 12 请输入第二个数字 5 |a / b| 2.4如果输入abc请输入第一个数字 abc 请输入第二个数字 5 输入不合法或除数为零无法计算。这类逐层return None的写法在真正的工程代码里很常见它的核心思想是一个函数只做一件事做不了就明确告诉调用者“我不行”而不是让异常一路往上抛。对初学者来说能写出这样的分层逻辑说明你已经从“把代码堆在 main 里”进化到“用函数拆解流程”的状态了。3.3 初学者最容易犯的几个“低级错误”批改时还发现一些重复率很高的小问题值得单独拿出来说变量名用了list、str、int。Python 里这些都是内置类型一旦你写了list [1, 2]后面再想用list()去创建新列表就会报TypeError: list object is not callable。中英文括号混用。编译器报SyntaxError: invalid character (UFF08)时很多人看不出来是中文括号。忘记缩进。Python 的缩进是语法的一部分第 5 行该缩进没缩进整个程序直接崩。数字和字符串直接比较。10 3在 Python 3 里直接报TypeError在 Python 2 里会得到奇怪的结果这也是为什么我从一开始就要求大家用 Python 3 的原因之一。这些“低级错误”听起来像废话但几乎每个人写头几百行 Python 时都会碰到。遇到也不用觉得丢脸把报错信息复制到搜索引擎搜一下看两三个回答基本就能明白。4. 第二关从一堆数据里“提炼信息”——手写聚合逻辑和 pandas 对照4.1 模拟数据长什么样任务二我提供了这样一份模拟数据截取了一部分sales [ {category: 书籍, quantity: 3, amount: 127.5}, {category: 电子产品, quantity: 1, amount: 2999.0}, {category: 书籍, quantity: 2, amount: 68.0}, {category: 服装, quantity: 2, amount: 399.0}, {category: 电子产品, quantity: 2, amount: 5198.0}, {category: 书籍, quantity: 5, amount: 235.5}, {category: 食品, quantity: 10, amount: 158.0}, {category: 服装, quantity: 1, amount: 199.0}, ]任务要求统计每个 “category” 的总数量和总金额按总金额从高到低排序输出。拿到这份数据正常人第一反应可能是“用 Excel 透视表”。但在 Python 里我们得先学会用代码做同样的事。毕竟真实项目的数据不可能每次都小到可以贴进 Excel。4.2 手写分组聚合理解 groupby 的本质“分组聚合”这个动作看起来很高端拆开就两步按哪个字段分组、对组内数据进行什么计算。手写实现其实就是一个字典字典的键是分组字段值是累积器from collections import defaultdict summary defaultdict(lambda: {quantity: 0, amount: 0.0}) for item in sales: cat item[category] summary[cat][quantity] item[quantity] summary[cat][amount] item[amount] # 排序输出 for cat, values in sorted(summary.items(), keylambda x: x[1][amount], reverseTrue): print(cat, values[quantity], round(values[amount], 2))输出电子产品 3 8197.0 书籍 10 431.0 服装 3 598.0 食品 10 158.0这里最有价值的地方是defaultdict。如果不用它你每次都要先判断if cat not in summary:再初始化代码会长一截。defaultdict的作用就是在你访问一个不存在的键时自动调用传入的工厂函数生成一个默认值省掉了手动判断的步骤。初学者把这个工具练熟之后写聚合类逻辑会顺手很多。排序那里的keylambda x: x[1][amount]也是一个值得吃透的写法。sorted默认按字典序排但我们要的是按金额数值排所以通过key指定排序依据。x是summary.items()里的一个元素——(分类名, 统计字典)这样的元组x[1]拿到统计字典再取[amount]就是金额了。4.3 用 pandas 验证结果numpy 和 pandas 的配合手写了一遍之后我叫大家再用 pandas 做一遍。这样做的目的不是为了“多此一举”而是让你同时理解“底层的逻辑”和“成熟的工具”。真实工作中你大概率直接写 pandas 一行搞定import pandas as pd df pd.DataFrame(sales) result df.groupby(category, as_indexFalse)[[quantity, amount]].sum() result result.sort_values(amount, ascendingFalse) print(result)如果你第一次接触groupby这个概念可以直接把它理解为“按照某个列把 DataFrame 切成很多个小块然后对每个小块执行同一个操作”。和手写循环的本质完全一样只是 pandas 把底层实现封装好了速度更快、写法更简洁。安装 pandas 的时候经常会连带安装 numpy因为 pandas 的底层数据结构依赖 numpy 数组。我之前在线下带过几个学员他们的电脑上pip install pandas之后import numpy没问题但import pandas报了很多 DDL 相关的错误。这类问题在 Windows 上多半是 numpy 版本和 Python 版本不匹配解决手段通常是pip uninstall numpy pandas pip install numpy pandas -i https://pypi.tuna.tsinghua.edu.cn/simple如果还不行可以考虑升级 Python 到较新的 3.11/3.12 版本然后重新建虚拟环境。一般来说新版 Python 的兼容性问题更少。4.4 写 CSV 时的两个坑编码和 Excel 打开乱码任务要求把结果保存成 CSV。很多人在这一步写成了result.to_csv(result.csv, indexFalse)用记事本打开没问题但用 Excel 双击打开时中文全变成了乱码。原因在于 pandas 默认保存 CSV 的编码是 UTF-8而 Windows 版 Excel 默认用 GBK 解析 CSV。解决办法是保存时指定编码result.to_csv(result.csv, indexFalse, encodingutf-8-sig)utf-8-sig会在文件开头加上一个 BOM 头Excel 识别到之后就会用 UTF-8 解析中文不再乱码。这个细节我不知道踩过多少次了每次帮别人排 CSV 乱码问题都得提一次。还有一个关于表格的经典疑问很多人说“Python 创建表格怎么只能 65536 行”——这其实不是 Python 的限制而是老版本 Excel.xls 格式的行数上限是 65536 行新版的 .xlsx 格式上限是 1048576 行。如果你用 pandas 导出to_excel默认生成的是 .xlsx通过 openpyxl完全可以容纳几十万行。报这个错一般是你在用一些老旧的库或者把数据写进了 .xls 格式。5. 第三关写一个“干净”的小爬虫公开接口也能练出手感5.1 先说清楚边界意识每次布置爬虫作业都有学员特别兴奋追着问“能不能爬某购物网站、能不能爬某社交媒体”。我的回答一直很明确这次作业只爬公开 API不教爬需要登录、有访问限制的站点。爬虫技术的核心价值在于“自动化获取公开数据”而不是绕过别人的风控体系。写爬虫之前至少要了解网站是否提供了官方 API如果有优先用官方 API。查看目标站点的robots.txt了解哪些路径允许被爬取。控制请求频率不要给对方服务器造成压力。不采集个人隐私信息和受版权保护的内容。本作业示例仅供学习实际应用中请遵守相关法律法规和网站服务条款。我在群里也强调过所谓“攻击类”的爬虫代码不但没有任何学习价值还会给自己惹上大麻烦坚决不能碰。5.2 请求一个公开的 JSON 接口为了让每个人都跑通我选用了一个公共的测试接口返回的是 JSON 格式的待办事项列表。接口路径类似https://jsonplaceholder.typicode.com/todos这是一个专门用于演示的公开服务返回的数据结构是列表每个元素是一个字典包含userId、id、title、completed四个字段。我们用它来统计已完成和未完成的数量。先写一个最简单的请求import requests url https://jsonplaceholder.typicode.com/todos resp requests.get(url, timeout10) print(resp.status_code) print(resp.text[:200])这里我特别强调一下timeout10。如果不指定超时时间程序会一直挂在那里等响应在网络环境差的时候非常难受。指定超时是写网络请求的底线习惯哪怕是在作业里也应该带上。5.3 解析 JSON 并统计resp.json()方法可以直接把 JSON 字符串解析成 Python 的列表和字典import requests from collections import Counter url https://jsonplaceholder.typicode.com/todos resp requests.get(url, timeout10) resp.raise_for_status() todos resp.json() status_counter Counter(item[completed] for item in todos) print(已完成数量, status_counter[True]) print(未完成数量, status_counter[False])Counter是collections模块里的一个小工具专门用来计数。这里传入的是一个生成器表达式每次取出一个completed字段的布尔值Counter统计每种值的出现次数拿到手就是一个现成的字典。这是“列表推导式/生成器表达式”的一个典型应用场景熟练之后写起来非常顺手。如果遇到requests抛 SSL 错误或者超时最简单的排查方式是检查网络代理设置有时候 VSCode 的代理插件会劫持 requests 的流量。把timeout调大一点比如 20再试一次。如果是公司内网限制需要配proxies{http: ..., https: ...}但这属于特殊情况作业里通常不需要。5.4 把结果写入 CSV 文件保存结果可以用 Python 标准库的csv模块也可以直接用 pandas。我建议这个阶段用标准库写一遍因为csv模块能让你直观地看到“逐行写入”的过程import csv with open(todo_summary.csv, w, newline, encodingutf-8-sig) as f: writer csv.writer(f) writer.writerow([状态, 数量]) writer.writerow([已完成, status_counter[True]]) writer.writerow([未完成, status_counter[False]])写文件时默认的newline是有讲究的。如果不写Windows 下 CSV 文件的行与行之间会出现空行因为writerow本身就会写一个换行符而open的文件对象在文本模式下会把\n转成\r\n于是每一行后面多了一个空行。这个坑在 Excel 里打开 CSV 时会特别明显写成newline之后问题消失。5.5 作业里常见的爬虫报错把这一环节交上来之后收到的问题集中在几类requests.exceptions.ConnectionError通常是没有网络或者被防火墙拦截。requests.exceptions.JSONDecodeError响应内容不是合法 JSON可以把resp.text打印出来看一下大概率是服务器返回了一个 HTML 错误页面。TypeError: string indices must be integers这说明你尝试在字符串上用整数索引比如item[0]但实际item是个字符串而不是字典。检查一下 JSON 结构用type(item)打印出来确认。这串报错排查的过程其实就是程序员日常工作的缩影。遇到问题不要慌先打印出来看数据长什么样再决定下一步怎么做。6. 第四关让作业有一点“作品感”——可视化和打包6.1 用 matplotlib 画一张真正有用的图附加题的第一部分是用 matplotlib 画图。大部分人会选择把任务二的“各分类销售金额”画成柱状图。这个选择很自然代码也不复杂import matplotlib.pyplot as plt categories [电子产品, 书籍, 服装, 食品] amounts [8197.0, 431.0, 598.0, 158.0] plt.figure(figsize(8, 5)) plt.bar(categories, amounts) plt.title(各分类销售金额) plt.xlabel(分类) plt.ylabel(金额元) plt.show()但这里有个非常经典的中文乱码问题默认字体不包含中文字符图上的标题和坐标轴文字会变成一个个小方框。解决方案是显式指定中文字体from matplotlib import font_manager # Windows 一般是 SimHei plt.rcParams[font.sans-serif] [SimHei] # 解决负号显示为方块的问题 plt.rcParams[axes.unicode_minus] False在 macOS 上可以换成[Arial Unicode MS]或[PingFang SC]。如果你是在服务器环境跑代码没有图形界面就把plt.show()换成plt.savefig(sales.png, dpi150)图片一样能保存下来。注意在无界面的 Linux 环境下直接show()不报错但是也不会弹窗口什么都没有所以要么写成savefig要么安装tkinter之类的 GUI 支持。6.2 趣味扩展爱心曲线、小游戏、ASCII 画很多初学者对这种“正经图”兴趣一般但看到“爱心代码”“Python 绘制人像画”“用 pygame 做小游戏”就会两眼放光。这完全可以理解毕竟学习兴趣是需要作品感来维持的。我鼓励大家把作业里学到的matplotlib、pygame等库拿去画一些有趣的东西。比如爱心曲线就是一个非常经典的 matplotlib 练习公式是x 16 * sin^3(t) y 13 * cos(t) - 5 * cos(2t) - 2 * cos(3t) - cos(4t)用代码画出来import numpy as np import matplotlib.pyplot as plt t np.linspace(0, 2 * np.pi, 1000) x 16 * np.sin(t) ** 3 y 13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t) plt.plot(x, y, colorred) plt.axis(equal) plt.show()类似的趣味项目还有很多比如“人狗大作战”这种命令行小游戏、用 turtle 模块画旋转图案、用 ASCII 字符输出图片的灰度图。我见过好几个学员就是因为先玩明白了这些项目回头再去做作业里的统计分析反而一点不觉得难了——因为代码量上来了思路自然就开窍了。换句话说不要把作业和“好玩的东西”对立起来作业里学到的列表推导式、字典、函数封装在小游戏和绘图项目里全用得上。“先有好玩的需求再补需要的知识”是自学编程最有效的路子。6.3 打包成 exe让没有 Python 的同学也能运行附加题里我留了一个 PyInstaller 打包挑战。这个题目看起来很酷但动手做的人并不多很多人是被“打包失败”劝退的。其实按顺序来并不复杂先在项目虚拟环境里安装pip install pyinstaller然后打包pyinstaller -F main.py-F表示打包成单个 exe 文件。编译过程结束后dist目录下会出现一个main.exe文件名取决于你的脚本名双击就能运行前提是对方的 Windows 系统有兼容的运行库正常都有。几个实战经验不要在全局环境打包。如果你电脑上同时装着很多包PyInstaller 会尝试把import到的所有依赖都打进去体积会很大。先建虚拟环境只装项目需要的包打包出来的 exe 会小很多也不容易因为一些无关依赖导致运行报错。exe 可能会被杀毒软件误报。因为 PyInstaller 打包的程序本质上是一个自解压的引导程序某些杀毒软件会把它当成未知程序。家里的电脑一般还好公司电脑高概率会被拦截。这不是你写了恶意代码放心就好。路径问题。如果你在代码里用相对路径读取外部文件双击 exe 后“当前目录”可能和你在 PyCharm 里运行时的“当前目录”不一样。简单粗暴的解决办法是把所有资源文件放到 exe 同目录下并且写路径时使用os.path.dirname(sys.executable)来定位 exe 所在目录而不是用相对路径。窗口程序用-w隐藏控制台。如果你的程序是图形界面或者只是一个小工具打包时加一个-w参数运行时就不会弹出黑色命令行窗口。但如果你写的程序是靠print和input交互的那么不能加-w否则黑窗口被隐藏了用户就没法输入了。打包这块我建议大家在正式学习完函数和文件操作之后再玩因为调试打包问题需要能读懂错误日志这比写代码本身更能锻炼“定位问题”的能力。7. 批改作业时的高频报错一次性说清楚7.1 按“病状”分类报错信息看了就懂每次批改作业我都能看到学员反复撞上同一类错误。这里整理一份高频表格如果你正在学习可以直接对照自查报错信息出现原因处理办法SyntaxError: invalid character (UFF08)用了中文括号、中文逗号编辑器中开启“显示空白字符”全改成半角符号IndentationError: unexpected indent某一行多缩进了统一用 4 个空格不要混用 TabNameError: name xxx is not defined变量名拼写错误或者忘了定义检查前后拼写注意大小写TypeError: unsupported operand type(s) for : int and str字符串和数字直接相加先用int()或float()转换IndexError: list index out of range访问了不存在的列表下标打印len(list)确认下标在范围内KeyError: xxx字典里没有这个键用dict.get(xxx)代替dict[xxx]ModuleNotFoundError: No module named pandas包没装或装到了别的环境确认解释器环境用正确 pip 安装ValueError: could not convert string to float: abc尝试把非数字字符串转数字转换前先检查字符串格式7.2 定位错误的通用方法从 Traceback 底部往上读很多初学者一看到一堆红色报错就慌其实 Python 的报错已经是非常友好的一门语言了。读报错只需要从最后一行往上读最后一行告诉你“发生了什么错误”它上面几行告诉你“在哪个文件、哪一行、哪个函数里发生的”。比如Traceback (most recent call last): File C:/Users/xxx/Desktop/homework/main.py, line 15, in module result safe_abs_divide(a, b) File C:/Users/xxx/Desktop/homework/main.py, line 9, in safe_abs_divide return abs(num_a / num_b) ZeroDivisionError: division by zero这里最核心的信息是最后一行ZeroDivisionError: division by zero意思是除数为零。看它上面两行发现错误发生在safe_abs_divide函数的return abs(num_a / num_b)这一行。于是你立刻知道num_b在这条路径上没有被正确处理成“非零”。回看代码就能发现num_b确实是0.0但函数里只判断了None没判断0。这种“从下往上读、逐层定位”的思路是排查一切程序错误的基本功。与其满屏乱猜不如把报错信息当作侦探线索一步步缩小范围。7.3 print 大法最简单有效的调试手段我到现在写代码还经常用print临时打印变量尤其是在数据不对但没报错的时候。什么情况会“数据不对但没报错”比如分组统计结果少了一个分类因为某个category的拼写和别的记录不一样“书籍”和“图书”。amount相加结果是一个很大的奇怪数字因为某些值其实是字符串自动拼接了而不是求和。爬虫拿到的是空列表因为 URL 少写了一个参数。遇到这类问题应该在关键节点打印变量的值print(sales[:3]) # 看看数据前 3 条长什么样 print(type(item[amount])) # 看看类型到底是不是 float print(summary) # 看看聚合每一步的结果这个习惯看起来笨但效率极高。Debugger 断点调试当然更专业但对初学者来说print大法能让你更快地建立“数据流”的心智模型你看到每一层输入是什么、输出是什么自然就能发现问题出在哪一层。8. 写在作业之外的小建议这次作业做下来我最大的体会是Python 的学习曲线不是一条直线而是一个个台阶。前几次作业是在夯实台阶第五次作业就是第一次跳跃。跳过去的人会对“用代码解决问题”这件事产生实打实的信心没跳过去的人往往会卡在“语法都会组合起来就不会”的尴尬阶段。我在实际批改过程中发现做得好的学员有一个共同习惯他们不止满足于“跑通”还会试着改一改题目条件比如把模拟数据换成真实的 Excel 文件把公开接口换成天气接口把柱状图换成饼图。这些“额外尝试”写出来的代码才是真正属于自己的经验。如果你也正在学 Python并且恰好要写一份像这样的综合作业我的建议是不用追求一次写完。先把任务一跑通再试任务二每完成一步就print一下结果确保每一步都是看得见的。遇到报错就按上面说的从最后一行开始读实在解决不了就问搜索引擎问的时候直接贴报错信息通常能找到现成答案。等你把五个关卡都过完再回头看看自己写的代码你会发现自己已经不知不觉具备了独立完成一个小型脚本项目的能力。