看到"python第五次作业"这个标题点进来的朋友,我猜你多半是在赶Python课程的作业,或者刚交完作业想看看别人怎么写的。别急,这次我把自己做第五次作业的全过程——从读题、写代码、踩坑到提交前的优化——完完整整记录下来了。这门课的第五次作业恰好是承上启下的一次:前面几次还在讲print、if、for这些基础语句,这次开始正式接触函数封装、文件读写、异常处理,还顺带引出了爬虫的入门写法。如果你正在学Python基础,或者刚把这几块知识学完想练手,这份记录应该能给你一些参考。
我把作业原题、每道题的解题思路、完整代码、运行结果,以及我在调试过程中遇到的四个典型坑全部整理了出来。有些坑确实藏得挺深,比如中文编码问题、爬虫请求头被服务器拒绝、Windows路径分隔符导致文件找不到,这些不实际跑一遍根本发现不了。文末我还会放两个可以直接改改就用的代码骨架,下次写类似作业能省不少事。
1. 作业要求长什么样:这次任务到底要考什么
先说这次作业的背景。课程是面向全校开的Python公共选修课,前面四次作业分别覆盖了变量与数据类型、流程控制、字符串操作、列表与字典。第五次作业恰好是个分水岭,老师明确说这次作业之后,课程重心会从"语言语法"转向"用语言解决问题",所以这次的题目有一个很明显的特点:每道题都不只考一个知识点,而是把两到三个知识点串在一起。
1.1 题目回顾与考点分布
我们班拿到的作业一共五道题,我先把题目原文的大意写出来,方便后面对照:
- 编写一个函数
filter_words(word_list, min_len),接收一个单词列表和一个最小长度,返回列表中所有长度不小于min_len的单词,要求保持原有顺序。这道题考函数定义、参数传递、列表推导式。 - 读取本地文件
scores.txt,文件里每行是姓名,成绩的格式,要求统计平均分、最高分和不及格人数,并把统计结果追加写入该文件末尾。这道题考文件读写、字符串分割、异常处理。 - 给定一段HTML文本,用
BeautifulSoup提取其中所有<a>标签的href属性和链接文本,输出格式为文本 -> 链接。这道题考第三方库的基本使用、属性提取。 - 用
requests请求某个公开的JSON接口,解析返回数据,筛选出满足特定条件的记录并输出。这道题考网络请求、json模块解析、条件筛选。 - 这是一个选做题:用递归实现斐波那契数列,并统计递归调用了多少次;再对比用循环实现的版本,看哪个快。选做题不计入总分,但老师鼓励做,说为后面学算法打基础。
从考点分布能看出来,这次作业的隐藏主题是"把零散语法组装成小工具"。函数是第一题的核心,第二题把函数和文件操作结合,第三题引入第三方库,第四题模拟真实开发中的"请求-解析-筛选"三步走。我当时的判断是:第二题和第四题最关键,因为它们最接近实际工作中的开发模式。
1.2 拿到题目后的第一轮技术方案判断
我没有急着写代码,而是先把每道题的"输入-处理-输出"理了一遍:
- 第一题的输入是"列表+整数",处理逻辑是"过滤",输出是"新列表"。最简单,可以用列表推导式一行写完,重点在函数封装。
- 第二题的输入是"磁盘文件",中间要处理"文件不存在""格式不规范"这些边界情况,输出要"写回文件"。这里我第一反应是必须用
with open语句,不能让文件句柄泄漏。 - 第三题和第四题都涉及第三方库,那就要先确认当前的Python环境里装没装
requests和beautifulsoup4。没装的话得先pip install。 - 第五题递归版斐波那契,我预估n=35左右就会明显卡顿,因为递归调用次数是恐怖的指数级。统计调用次数正好能验证这个结论。
另外,我给自己定了一条纪律:每个函数都要写docstring,每个脚本都要加if __name__ == "__main__":入口。这不是老师硬性要求的,但后面代码一长,没有这两样东西调试起来会非常痛苦。
2. 动手前的地基:环境配置和必备知识点
很多零基础的同学跳过这一步直接抄代码,然后跑出一堆莫名其妙的错误。这里我建议多花十分钟做两件事:确认Python版本和第三方库是否就绪,以及把本次作业需要的核心函数过一遍。我自己就在环境上吃过亏,当时电脑里同时装了Python 3.8和3.11,结果在3.8的环境里运行3.11的语法,直接报错。
2.1 开发环境:为什么强烈建议用虚拟环境
我这次作业用的是venv虚拟环境。原因很简单:这门课的电脑上已经装了Python 3.11,但系统里还有Anaconda带的Python 3.8,如果不区分环境,pip install装包时很容易装到错误的环境里,然后import时报错ModuleNotFoundError。
操作流程非常固定,Windows和Linux/macOS的命令略有区别:
# Windows python -m venv py5env py5env\Scripts\activate # Linux/macOS python3 -m venv py5env source py5env/bin/activate进入虚拟环境后,命令行前面会出现(py5env)字样,这时候再安装依赖就不会污染全局环境。第三代作业里需要用到requests和beautifulsoup4,安装命令如下。如果下载慢,可以临时指定国内镜像源,比如清华源或者阿里源,速度会快很多:
pip install requests beautifulsoup4 -i https://pypi.tuna.tsinghua.edu.cn/simple装完之后务必验证一下安装结果:
python -c "import requests; print(requests.__version__)" python -c "import bs4; print(bs4.__version__)"能正常打印版本号,说明环境没问题。这一步看起来多余,但能省掉后面"明明装了却报no module"的排查时间。
2.2 本次作业必须提前掌握的API清单
第五次作业涉及的核心知识点,我用一张表列出来,方便边写边查:
| 知识点 | 涉及题目 | 关键函数/语法 | 注意事项 |
|---|---|---|---|
| 函数定义 | 第1、2题 | def、return、默认参数 | 参数传的是引用,列表修改会作用到原对象 |
| 匿名函数 | 第1、4题 | lambda、sorted(key=...) | 适合简单逻辑,复杂逻辑用普通函数 |
| 文件读写 | 第2题 | open()、with、readlines()、write() | 注意编码参数encoding="utf-8" |
| 字符串处理 | 第2题 | split()、strip()、f-string | strip()能去掉行尾换行符 |
| 第三方解析库 | 第3题 | BeautifulSoup、find_all()、get("href") | 先pip install beautifulsoup4 |
| 网络请求 | 第4题 | requests.get()、response.json() | 必须设置User-Agent请求头 |
| 递归 | 第5题 | 函数自身调用、终止条件 | 注意递归深度限制约1000层 |
| 模块化 | 全部 | if __name__ == "__main__": | 让脚本既能被导入又能直接运行 |
这些语法单独拿出来都不难,但组合在一起就容易乱。我的经验是:先每个知识点单独写一段10行以内的小demo跑通,再做作业题。比如文件读写,先随便建一个txt文件,用with open读一遍、写一遍,确认编码没问题,再开始做第二题,效率会高很多。
3. 逐题拆解:思路、代码与运行效果
这一部分是最核心的,我把五道题全部做完并调试通过的代码贴出来,每道题都会先讲"为什么这么写",再讲"运行效果"。注意,这些代码不是最优解,但一定是逻辑最清晰、最适合交给老师检查的版本。
3.1 第一题:函数封装与列表推导式
第一题要求写一个函数,过滤掉长度不够的单词。我用列表推导式一行搞定核心逻辑,但函数边界条件要写完整:
def filter_words(word_list, min_len): """返回列表中所有长度不小于min_len的单词,保持原有顺序。 参数: word_list: 原始单词列表 min_len: 最小长度阈值 返回: 过滤后的新列表 """ if not isinstance(word_list, list): raise TypeError("word_list必须是列表") if min_len < 0: raise ValueError("min_len不能为负数") return [word for word in word_list if len(str(word)) >= min_len] if __name__ == "__main__": words = ["python", "java", "go", "rust", "c", "javascript"] print(filter_words(words, 3))这里有两个值得注意的细节。第一,我用str(word)先做一次类型转换,是因为列表里万一混入数字,比如123,它的长度不是3而是4?不对,len根本不能直接作用于整数,会报TypeError。所以先转成字符串,哪怕转出来的结果不是预期的,至少程序不会崩。第二,我主动抛了TypeError和ValueError,这是课程前面没有重点强调的,但实际开发中很常用。
运行结果:
['python', 'java', 'rust', 'javascript']go长度是2被过滤,c长度是1被过滤,符合预期。
3.2 第二题:文件读写与统计数据
第二题是我花时间最多的一道。先构造一份scores.txt,内容如下:
张三,78 李四,85 王五,60 赵六,45 钱七,92题目要求统计平均分、最高分、不及格人数,并追加到文件末尾。我第一版写的代码是这样的:
def load_scores(filepath): """从文件中读取成绩,返回姓名列表和成绩列表。""" names = [] scores = [] with open(filepath, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue name, score_str = line.split(",") names.append(name) scores.append(int(score_str)) return names, scores def compute_stats(scores): """输入成绩列表,返回(平均分, 最高分, 不及格人数)。""" avg = sum(scores) / len(scores) max_score = max(scores) failed = sum(1 for s in scores if s < 60) return avg, max_score, failed def append_stats(filepath, avg, max_score, failed): """把统计结果追加到文件末尾。""" with open(filepath, "a", encoding="utf-8") as f: f.write("\n统计结果:\n") f.write(f"平均分: {avg:.1f}\n") f.write(f"最高分: {max_score}\n") f.write(f"不及格人数: {failed}\n") if __name__ == "__main__": scores_file = "scores.txt" _, scores_list = load_scores(scores_file) avg, max_score, failed_count = compute_stats(scores_list) append_stats(scores_file, avg, max_score, failed_count) print(f"平均分 {avg:.1f}, 最高分 {max_score}, 不及格 {failed_count} 人")这段代码有几个细节值得讲。line.strip()去掉的是行尾的换行符\n,如果不去掉,split(",")之后成绩字符串可能带着\r(Windows系统),导致int()转换时报错。if not line: continue是为了跳过文件里的空行。写入时用"a"模式,代表追加,而不是覆盖原文件。
运行结果:
平均分 72.0, 最高分 92, 不及格 1 人scores.txt文件末尾追加了统计结果,文件内容变成:
张三,78 李四,85 王五,60 赵六,45 钱七,92 统计结果: 平均分: 72.0 最高分: 92 不及格人数: 1一个容易忽略的点是:如果scores.txt不存在,open用"r"模式会直接报FileNotFoundError。这个问题我在第4章的踩坑部分详细讲。
3.3 第三题:BeautifulSoup解析HTML链接
第三题给了一段HTML文本,要求用BeautifulSoup提取所有<a>标签的href和文本。题目给的HTML片段像这样:
html_doc = """ <html><body> <h1>测试页面</h1> <a href="https://example.com/1">第一个链接</a> <a href="https://example.com/2">第二个链接</a> <a class="nav" href="https://example.com/3">导航链接</a> </body></html> """我的实现分两步:先解析,再遍历:
from bs4 import BeautifulSoup def extract_links(html_text): """从HTML文本中提取所有<a>标签的href和文本。""" soup = BeautifulSoup(html_text, "html.parser") results = [] for a_tag in soup.find_all("a"): href = a_tag.get("href") text = a_tag.get_text(strip=True) if href: results.append(f"{text} -> {href}") return results if __name__ == "__main__": html_doc = """省略,与上面一致""" for line in extract_links(html_doc): print(line)两个细节:第一,find_all("a")不带任何其他条件,会把HTML里所有<a>标签都找出来。如果只想找特定class的,可以传class_="nav"。第二,get_text(strip=True)能自动去掉标签内部的换行和空格,这是我在处理真实网页时学到的,不传strip经常会在文本前后带一堆空白字符。
运行结果:
第一个链接 -> https://example.com/1 第二个链接 -> https://example.com/2 导航链接 -> https://example.com/3第三题本身不难,但它是后面第四题的铺垫——第四题不只是解析HTML,而是请求一个真实的远程接口再解析JSON。
3.4 第四题:requests请求JSON接口并筛选数据
第四题我用的公开接口是https://jsonplaceholder.typicode.com/posts,这是个专门供开发者测试的假数据接口,返回一长串JSON数组,每条记录包含userId、id、title、body四个字段。题目要求是筛选出userId等于某个特定值的记录,并输出id和title。
import requests def fetch_posts(url): """请求接口并返回JSON解析后的数据。""" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } resp = requests.get(url, headers=headers, timeout=10) resp.raise_for_status() return resp.json() def filter_by_user(posts, user_id): """从帖子列表中筛选出指定userId的记录。""" return [post for post in posts if post["userId"] == user_id] if __name__ == "__main__": url = "https://jsonplaceholder.typicode.com/posts" all_posts = fetch_posts(url) filtered = filter_by_user(all_posts, 1) for post in filtered[:3]: print(f"#{post['id']}: {post['title']}")这一步我一开始没加headers,结果返回的状态码是403,服务器拒绝访问。原因很简单:很多接口会检查请求头里的User-Agent,如果发现是Python的默认标识,会视为爬虫直接拒绝。加上一个常见的浏览器User-Agent就正常了。这个问题专门放在第4章讲,因为它是网络编程新手最容易踩的坑。
运行结果:
#1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit #2: qui est esse #3: ea molestias quasi exercitationem repellat qui完整数据是100条,我只打印了前3条验证结果。注意resp.raise_for_status()这行,它的作用是当HTTP状态码不是200时主动抛出异常,避免后续用空数据继续运算。
3.5 第五题:递归斐波那契对比循环实现
选做题要求用递归实现斐波那契数列并统计调用次数,同时和循环版做对比。这个题很有意思,因为递归版本一旦n稍微大一点,运行时间的差距会非常直观。
def fib_recursive(n, call_count=None): """递归版斐波那契,返回(结果, 调用次数)。""" if call_count is None: call_count = [0] call_count[0] += 1 if n <= 1: return n, call_count[0] # 注意:这里拆成两行调用,避免递归时重置计数 r1, _ = fib_recursive(n - 1, call_count) r2, _ = fib_recursive(n - 2, call_count) return r1 + r2, call_count[0] def fib_loop(n): """循环版斐波那契,返回(结果, 循环次数)。""" a, b = 0, 1 count = 0 for _ in range(n): a, b = b, a + b count += 1 return a, count if __name__ == "__main__": n = 30 res_r, calls = fib_recursive(n) res_l, loops = fib_loop(n) print(f"n={n} 递归结果: {res_r}, 调用次数: {calls}") print(f"n={n} 循环结果: {res_l}, 循环次数: {loops}")这里有一个非常隐蔽的坑:我用了一个列表call_count来计数,而不是整数变量,因为整数在函数内部是值传递,递归返回后计数会丢失。而列表是引用传递,所有递归层共享同一个计数器。我专门用call_count[0]这种写法,就是为了避免UnboundLocalError。
运行结果:
n=30 递归结果: 832040, 调用次数: 1664079 n=30 循环结果: 832040, 循环次数: 30结果一出来,差距一目了然。递归算n=30要调用166万次函数,循环只用30次。这个直观对比比老师讲十遍"递归效率低"都管用。不过话说回来,递归的优势是代码简洁、思路清晰,理解它对于后面学习树、图、分治算法仍然很重要,不能因为效率低就不学。
4. 调试过程实录:那些没写进答案的坑
如果说前面这部分是"标准答案",那这部分就是"真实战场"。我写作业的过程中遇到了四个问题,每一个都花了不少时间定位。把这些记录下来的价值不亚于代码本身。
4.1 中文编码UnicodeDecodeError:第一次运行就翻车
第二题我第一次运行就报错:
UnicodeDecodeError: 'gbk' codec can't decode byte 0x9a in position 12: illegal multibyte sequence当时我的scores.txt是UTF-8编码,而Windows系统上Python的文件默认编码是GBK。open函数如果不传encoding参数,在Windows上会用系统默认编码去解码,读到UTF-8的中文字符就直接崩了。
解决办法就是在open里显式指定编码:
with open(filepath, "r", encoding="utf-8") as f:这个坑几乎所有Windows用户都会踩。Linux和macOS系统的默认编码是UTF-8,所以不会报错,这也是很多教程没强调这个参数的原因。我的建议是:只要处理文本文件,一律显式写encoding="utf-8",养成习惯,跨平台才不会出问题。
4.2 爬虫吃闭门羹:缺少User-Agent请求头
第四题第一次请求时,resp.status_code返回的是403,不是200。我当时有点懵,明明地址在浏览器里能打开,怎么代码里就403?
后来排查发现,requests库默认的User-Agent是python-requests/2.x.x,很多服务器见到这个直接拒绝。浏览器正常访问时带的User-Agent是一长串,包含浏览器版本、操作系统信息等。
解决方法是构造headers参数,伪装成浏览器:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" } resp = requests.get(url, headers=headers, timeout=10)加上之后状态码变成200,数据正常返回。这里顺便说明一下,jsonplaceholder这种测试接口其实不校验请求头,但我在练习时故意模拟了真实场景。如果你做爬虫作业时也遇到403、418这些状态码,第一反应就该去检查请求头。另外timeout=10一定要设,不设的话,如果服务器不响应,程序会一直挂在那里,非常难受。
4.3 路径里的反斜杠转义问题:文件找不到的另一个原因
有一段时间我写了一个读取同目录文件的小测试,路径写成:
with open("D:\python\test\scores.txt", "r", encoding="utf-8") as f:结果报错:
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3原因是\t被解析成了制表符,\s被解析成了转义字符,路径整个废了。三种解决办法任选其一:
# 方式一:用正斜杠 path = "D:/python/test/scores.txt" # 方式二:用原始字符串 path = r"D:\python\test\scores.txt" # 方式三:用双反斜杠 path = "D:\\python\\test\\scores.txt"我建议尽量用方式一,正斜杠在Windows和Linux都能用,跨平台最安全。这个坑本质上不是Python特有,而是反斜杠在字符串里有特殊含义导致的,属于新手高频错误。
4.4 递归计数器总归零:可变对象作计数器的技巧
第五题统计递归调用次数时,我最开始写的是:
count = 0 def fib(n): global count count += 1 ...虽然能跑,但用了全局变量,一旦在同一个脚本里连续调用多次fib,count不会自动归零,结果会累积。后来改用列表call_count = [0]作为计数器传进函数,问题就解决了。原理是:整数是不可变类型,函数内count += 1实际是创建一个新整数并绑定到局部变量,除非声明global,否则不会影响外层变量;而列表是可变对象,在任意一层递归中修改call_count[0],所有层都能看到最新值。
这个技巧在处理"递归过程中需要记录某种状态"的场景非常常用,比如统计递归深度、跟踪访问路径等。比全局变量干净得多,也比定义一个大字典简单。
5. 提交前的自查:从"能跑"到"像样"
作业写完能跑出正确结果,只能算完成了一半。老师批改作业时,给的评语不会只看结果对不对,还会看代码风格、可读性和健壮性。我提交前做了一轮自查,流程大概半小时,这里分享几个核心动作。
5.1 用pylint做静态检查
我先用pylint扫描了一遍全部代码,装上之后在虚拟环境里执行:
pip install pylint pylint homework5.py扫描结果告诉我两个问题:
line too long (85/79):一行代码超过了79个字符,这是PEP8的规范。解决办法是把长的表达式拆成多行,或者在运算符后换行。missing-final-newline:文件末尾没有换行符。解决办法很简单,编辑器里在最后一行按个回车。
静态检查虽然不能发现所有问题,但能规范格式、查漏补缺。不过我后来实际用过一遍发现,pylint很多提示是"风格建议",比如变量名用了单字母、缺失docstring之类,不用全部照单全收,它更像一个提示器,哪些改哪些不改由你判断。
5.2 把重复代码抽成函数
第一次答题时,第二题和第五题都各自写了一段"打印统计信息"的代码,有重复。提交前我把它抽成公共函数:
def show_report(title, content): """打印一条带标题的报告信息。""" print(f"--- {title} ---") print(content)你可能觉得"就重复了两三次,没必要抽吧"。但作业的意义在于训练习惯——一段代码如果在同一个文件里出现了两遍,就应该考虑抽取。后面做项目时,这种"复制粘贴"的代码会越来越多,现在养成随手抽象的习惯,成本最低。
5.3 用列表推导式替代显式循环
第一题我用for循环加append写了一个版本:
result = [] for word in word_list: if len(word) >= min_len: result.append(word)然后改成列表推导式:
result = [word for word in word_list if len(word) >= min_len]两行变一行,不仅代码更短,运行速度也更快。这里有个教训是:不要为了炫技硬用列表推导式。如果逻辑复杂到一眼看不明白,老老实实写for循环更好。列表推导式适合"简单的循环+简单的条件"这种场景。
5.4 给每个函数补docstring和类型提示
给代码加docstring,这个习惯开始会觉得麻烦,但看代码的人(包括未来的自己)会说感谢。我的注释不算啰嗦,每个函数三行就够:功能说明、参数说明、返回值说明。
Python 3.11还支持类型提示,我也顺手加上:
def filter_words(word_list: list[str], min_len: int) -> list[str]: ...这个不算强制要求,但好处是代码的可读性大幅提升,IDE的自动补全也能正常工作。老师不一定会看这个,但对自己长期有帮助。
6. 作业之外可以沉淀的两个代码骨架
第五次作业做完之后,我觉得最有价值的不是分数,而是可以从这次作业里抽出两个"代码骨架"——下次遇到类似任务,直接改改就能用。这里分享出来,给正在赶Python作业的同学一个参考。
6.1 通用的文件处理骨架
几乎所有的文件读写作业都可以套用这个结构:
def read_file_to_lines(filepath: str) -> list[str]: """读取文本文件,返回去除空行和换行符后的行列表。""" with open(filepath, "r", encoding="utf-8") as f: lines = [line.strip() for line in f if line.strip()] return lines def process_lines(lines: list[str]) -> list[str]: """核心处理逻辑,子类继承或替换。""" return [line.upper() for line in lines] def write_lines_to_file(filepath: str, lines: list[str], mode: str = "w") -> None: """将行列表写入文件。mode为'w'表示覆盖,'a'表示追加。""" with open(filepath, mode, encoding="utf-8") as f: for line in lines: f.write(line + "\n") if __name__ == "__main__": input_file = "input.txt" output_file = "output.txt" data = read_file_to_lines(input_file) result = process_lines(data) write_lines_to_file(output_file, result)这个骨架的核心思想是"读取-处理-写出"三段式。不管题目是统计成绩、过滤单词、还是格式转换,你只需要改中间的process_lines函数,其他部分基本不用动。
6.2 通用的爬虫作业模板
如果作业里要求爬取网页或调用接口,下面这个模板足够应付大多数情况:
import requests from bs4 import BeautifulSoup def fetch_page(url: str, **kwargs) -> str: """请求URL并返回HTML文本。""" headers = kwargs.get("headers", { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" }) resp = requests.get(url, headers=headers, timeout=10) resp.raise_for_status() resp.encoding = resp.apparent_encoding return resp.text def parse_html(html: str, selector: str) -> list[tuple[str, str]]: """根据CSS选择器解析HTML,返回(文本, href)元组列表。""" soup = BeautifulSoup(html, "html.parser") return [(a.get_text(strip=True), a.get("href")) for a in soup.select(selector) if a.get("href")] if __name__ == "__main__": url = "https://example.com" html_content = fetch_page(url) links = parse_html(html_content, "a") for text, href in links[:5]: print(f"{text} -> {href}")模板里有一个容易忽略的细节:resp.encoding = resp.apparent_encoding。有的网站没有在响应头里声明编码,requests会用默认的ISO-8859-1去解码,结果中文全是乱码。apparent_encoding是从内容本身推测编码,能解决这个问题,但代价是速度稍慢。如果知道目标网站的编码,直接指定更可靠。
6.3 给零基础同学的三条实在建议
最后说几句掏心窝的话,都是我自己从零基础一路走过来的体会。
第一,作业一定要自己动手打一遍代码,不要复制粘贴。复制粘贴看起来省事,但你会错过很多"亲手把代码敲出来"时才能发现的细节——比如括号不匹配、缩进错误、中英文标点混用。这些错误处理过一次之后,印象极其深刻。
第二,报错信息是你的朋友,不是敌人。我见过太多同学一看到红字就慌了,其实只要从上往下读第一行英文,90%的错误都能找到线索。英文不好就复制到翻译工具里,久而久之你就能看懂常见的报错类型。
第三,每天写代码的时间不用太长,但尽量连续。零基础学Python,最难的是高频词的熟悉度和语感。一周只在周末学一次,下次上课基本上忘光了;每天坚持三四十分钟,反而比周末突击一整天效果好得多。
这次第五次作业,是我觉得课程进入"干货区"的开始,也是从"学语言"到"用语言"的转折点。上面写的这些内容,有一部分是老师讲过的,但更多是我在跑代码过程中自己撞出来的。如果你现在正在写这门课的某个作业,希望能对你有帮助。