Python零基础三个月学习实录:从环境搭建到量化回测

📅 发布时间:2026/10/8 9:29:58
Python零基础三个月学习实录:从环境搭建到量化回测
3.14 这天我给自己的三个月Python学习画了个逗号3月14号正好是圆周率日。对于写Python的人来说这个日子有点天然的亲切感——毕竟这门语言从诞生起就跟数学、数据、算法这些词绑在一起而浮点数里头天天都能见到3.1415926的影子。我选在这一天写这篇Python学习记录说实话没刻意安排但回头看倒像是个不错的仪式感学了三个多月从完全零基础到能写一点小工具、小爬虫、小脚本正好需要停下来梳理一下。这篇记录不是什么大神教程就是一个普通学习者把自己踩过的坑、看懂的代码、绕过的弯路原原本本摆出来。适合谁看呢如果你正准备学Python、刚开始学Python或者学了几天感觉一片混乱那这篇东西应该能给你一点参考。我不打算只堆知识点我会把当时为什么会这么学、哪些地方卡住了、最后怎么解决的全部说清楚。毕竟变量、切片、函数、协程这些东西官方文档都写得很全真正缺的是一个过来人告诉你“这里别死磕那里要细看”。1. 学Python之前我先想明白了这三件事1.1 为什么是Python而不是Java或C刚开始的时候我也犹豫过。Java岗位多、C性能强、Go看起来又新又酷为什么最后选Python我的判断很简单第一我当时的目标不是立刻找工作而是想尽快具备“用代码解决实际问题”的能力第二Python的语法结构接近自然语言变量不用声明类型、缩进代替花括号对于零基础的人来说入门门槛确实低很多第三生态太全了——爬虫有requests数据处理有numpy和pandas画图有matplotlib写自动化脚本更是天生擅长。打个不太严谨的比方C像一台手动挡赛车性能上限极高但你必须先精通离合换挡才能上路Java像一辆公交车规矩多、结构严谨适合大公司多人协作Python则像一把瑞士军刀什么事都能干一点且上手就能用。对于一个“先用起来、建立信心”的阶段来说没有比Python更合适的了。等你以后真的有性能需求、或者特定方向深入了再补C或者Java也不迟——语言是工具不是信仰。1.2 把学习切成能落地的阶段而不是“学完再动手”我见过太多人学Python的方式是买一本几百页的书从第一章挨着看到最后一章看到一半发现前面的全忘了于是放弃。我自己的策略刚好相反——“用中学学中用”。我把三个月的学习分成了四个阶段第一阶段是基础语法花了两周只学最核心的东西变量、数据类型、条件判断、循环、函数、列表和字典。目标不是“精通”而是“看得懂代码在干什么”。第二阶段是常用库花了两到三周重点学了numpy、matplotlib、requests这几个库。这一阶段开始做小项目比如拉一个网页、解析数据、画一张图。第三阶段是进阶话题包括文件操作、异常处理、面向对象、还有并发编程里的协程和队列。这段时间比较痛苦因为概念开始抽象了。第四阶段是回归项目把之前学的零碎知识点整合起来做了几个完整的小东西比如爬虫脚本、数据可视化报表、还有量化交易的双均线回测。这么设计的原因是人的短期记忆容量有限如果一个知识点学了之后得不到应用两天就还给课本了。反而是那些“因为需要所以去查、因为报错所以去修”的知识记得特别牢。1.3 学习资料别贪多认准一套主粮其他都是辅食我推荐给新手的组合其实很简单官方文档当字典查菜鸟教程或者廖雪峰的Python教程当主线读GitHub上找开源项目当练习册。千万不要同时收藏十几个教程今天看A老师的视频、明天看B老师的博客每个老师的讲解顺序和术语习惯都不一样最后只会把自己搞晕。我自己的做法是主线用廖雪峰的教程过一遍基础遇到不懂的函数直接去翻官方文档。不要怕官方文档英文——Python官方文档的结构非常清晰查几次就会了。另外我强烈建议新手尽早用上GitHub哪怕只是去clone几个项目下来读代码。比如我在学requests库的时候就找了一个开源爬虫项目把它的代码一行一行读过去弄清楚每个函数是干什么的比单纯看教程效率高很多。2. 从安装到能跑环境搭建的黑历史2.1 版本选择为什么我停在3.8如果你现在去Python官网下载默认会推荐最新的稳定版比如3.12或3.13。但我在3月这个节点特意选择了Python 3.8版本。原因很简单很多第三方库的兼容性还停留在旧版本上尤其是量化交易、机器学习和某些GUI相关的库。我在装numpy的时候发现3.8版本的所有轮子都是齐全的而最新版本偶尔会因为编译环境问题导致安装失败。对于零基础的人来说我建议直接用官网的安装包注意勾选“Add Python to PATH”这个选项。很多新手装完Python之后在命令行敲python却提示找不到命令十有八九就是这一步没勾选。如果已经装完了才发现PATH里没有可以手动打开系统环境变量设置把Python的安装目录和Scripts目录加进去。我的安装路径默认在C盘由于路径中有空格虽然Python本身能正常工作但个别第三方库在安装时会出现路径解析问题。后期如果遇到莫名奇妙的报错可以考虑把Python安装在无空格的纯英文路径下——这是我踩过的一个小坑。2.2 Linux上的安装方式与Windows差异除了Windows我也在Linux系统上安装过Python因为后面学习爬虫和数据分析时很多服务需要在服务器上跑。Linux安装Python最稳妥的方式是源码编译先去官网下载源码包解压后依次执行configure、make、make install三步。但编译前一定要装好依赖比如zlib、libffi、openssl-devel这些否则装完的Python会缺少某些模块而且这种缺失在运行的时候才会暴露排查起来非常折磨。Windows和Linux的环境差异比很多人想象中更大。Windows下安装库一般直接用pip install就能解决但Linux上有时需要先安装python3-pip。还有一点Linux系统自带的Python版本往往比较旧比如CentOS默认还是Python 2.7或者3.6如果你有root权限并且不影响系统工具的前提下建议自己编译一份新的Python装到/usr/local目录里用绝对路径去调用避免和系统自带的Python打架。2.3 和pip打好交道换源是第一步Python的库管理全靠pip但默认的官方源在国外安装稍微大一点的包比如numpy、pandas速度可能慢到让你怀疑网线断了。我刚学的时候装一个库等了十几分钟后来才知道可以换国内镜像源。随手写个配置pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple换完之后速度立竿见影。另外当你看到“Requirement already satisfied”的时候说明这个库已经装过了pip不会重新安装看到“WARNING: You are using pip version 20.3.3”的时候可以顺手升级一下pip本身但新手期如果不升级也不影响使用。我还注意到一个问题有些情况下pip安装库会提示 “externally managed environment”这是新版Python对环境隔离的保护机制意味着直接pip install会被系统拦截。这种情况下你最好建一个虚拟环境再安装或者直接使用包管理器安装。不过虚拟环境这个概念等学了一两周之后再熟悉也不迟新手期先别被这些概念吓住。注意不要从不明来源复制所谓“免费源码”或“一键脚本”直接运行这几年网上流传过很多恶意Python脚本表面上是爬虫或者小工具实际上是窃取本机文件或者挖矿程序。源码可以读、可以拆解但不明用途的代码不要轻易执行。3. 基础语法从变量到函数一次讲顺3.1 变量、类型与类型转换动态语言的双刃剑Python的变量不需要声明类型这给新手省了不少麻烦但也带来了一个隐性问题你根本不知道一个变量现在是什么类型。我写过一个简单例子a 1 # 整数 a hello # 字符串 print(a)这种写法在C语言里会直接报错但在Python里完全合法。好处是灵活坏处是代码写多了之后你可能会忘记某个变量是字符串还是列表然后对字符串用索引切片或者对一个整数调用字符串方法运行到一半才报TypeError。所以我的经验是重要变量可以用命名来暗示类型比如user_name、price_list、is_valid虽然Python没有强制要求但读代码的人会舒服很多。类型转换是初学的第一个坎。int()、float()、str()这几个内置函数就是干这个的。举个例子从网页上抓回来的数据大多是字符串比如23.45你想做数学运算必须先float(23.45)转成浮点数。而当你把字符串转成整数的时候有个细节容易踩坑int(3.14)会直接报错因为int()不接受带小数点的字符串你得先float(3.14)再int()结果或者直接int(3.14)后者会自动截断小数部分变成3。我为了巩固变量和类型的知识当时自己出了一组练习题大概包括给定一个字符串拆分出数字和字母把列表里的字符串数字全部转成整数并求和判断一个变量是什么类型。看着简单但真写起来会发现很多细节问题。建议你也试试别光看教程不动手。3.2 切片Python最优雅的语法之一数组和列表的切片是我学Python以来觉得最值的功能。它的基本形式是list[start:stop:step]比如arr [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(arr[2:8]) # [2, 3, 4, 5, 6, 7] print(arr[:4]) # [0, 1, 2, 3] print(arr[::2]) # [0, 2, 4, 6, 8] print(arr[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]负索引和负步长是切片的精髓。arr[-1]取最后一个元素arr[-3:]取最后三个元素arr[::-1]则是整个列表反转。这个特性在做数据筛选、图像处理、文本逆序的时候简直不要太方便。我在用numpy处理矩阵的时候切片语法几乎一模一样所以基础阶段的练习非常值得花时间。我见过很多人学切片时会犯一个认知错误以为切片是复制数据。其实切片返回的是新列表但里面的元素仍然是原对象的引用。如果元素是可变对象比如列表本身修改切片中的子列表同样会影响原列表。这个点不弄清楚以后调试bug会非常痛苦。3.3 筛选“一样的”数据去重与查找重复项热搜词里有一条叫“python筛选一样的”我猜说的就是从一个列表里找出重复元素或者把重复项去掉。最简单的去重用setdata [1, 2, 2, 3, 3, 3, 4] unique list(set(data))set的去重特性是基于哈希的速度快但去重之后原来的顺序就不一定保留了。如果你既要保留顺序又要去重可以这样写seen set() result [] for item in data: if item not in seen: seen.add(item) result.append(item)查找重复项也很常见。比如你有一个列表想知道哪些元素出现了不止一次可以用Counterfrom collections import Counter counter Counter(data) duplicates [k for k, v in counter.items() if v 1]Counter这个类在爬虫数据分析时用得很多不只是统计数据频率它本质上就是一个带计数的字典。学会这个你后面处理文本词频、统计标签分布的时候会轻松很多。3.4 定义函数从重复代码到抽象思维函数是结构化编程的基础。我刚开始学的时候觉得函数就是“把代码装进盒子里再给它取个名字”直到写了一段十几行重复代码才意识到函数的真正价值它把“怎么做”和“在哪里做”分开了。Python定义函数用def关键字支持位置参数、默认参数、关键字参数。比如def calculate_price(price, discount0.8, tax0.13): final_price price * discount * (1 tax) return round(final_price, 2)这里discount和tax都有默认值调用时你可以只传price也可以指定discount0.9。Python的默认参数有一个经典陷阱不要用可变对象做默认参数比如def func(lst[])这样所有调用共享同一个列表容易出诡异bug。正确写法是def func(lstNone)然后在函数内部if lst is None: lst []。提醒学函数的时候一定要把“返回值”这个概念吃透。Python函数如果没有return默认返回None。很多新手写了一个函数调用之后却得到None就是因为忘了在函数末尾return。4. 画图、矩阵与数据可视化让结果看得见4.1 横坐标太密集三招解决matplotlib是Python最常用的绘图库。我刚开始画图时遇到最多的问题就是数据量一大横坐标的刻度标签全都挤在一起密密麻麻像乱码。我当时数据大约有100个点默认显示的刻度全堆在一起完全没法看。解决办法有三个。第一个是旋转标签让文字斜着排import matplotlib.pyplot as plt plt.xticks(rotation45)第二个是设置刻度间隔只显示其中的一部分import numpy as np x np.arange(100) plt.xticks(np.arange(0, 100, 10))第三个是使用autofmt_xdate或者设置figsize把画布拉宽让每个刻度有足够空间。我最常用的组合是画布尺寸调大 旋转45度 手动指定要显示的刻度位置。还有一个小技巧如果你的横坐标是时间序列matplotlib会自动优化刻度密度但有时还是会挤可以结合AutoDateLocator做更精细的控制。4.2 保存图片跳出分辨率陷阱用plt.show()看图表没问题但想保存成图片用作报告素材时新手经常保存出来的图片模糊不清。原因很简单默认dpi只有100。保存时建议明确指定dpi和尺寸plt.figure(figsize(12, 6)) plt.plot(x, y) plt.savefig(result.png, dpi300, bbox_inchestight)bbox_inchestight的作用是自动裁掉多余的白边特别是标题或坐标轴标签被截断的时候这个参数能救回半张图。如果你要打印或者插入论文dpi至少要300如果只是在屏幕上看150就够。4.3 用numpy构建邻接矩阵邻接矩阵这个概念来自图论它用矩阵来表示图中各个节点之间的关系。假设有4个节点节点之间的边有5条用0和1表示n 4 edges [(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)] adj_matrix np.zeros((n, n), dtypeint) for i, j in edges: adj_matrix[i][j] 1 adj_matrix[j][i] 1 # 无向图 print(adj_matrix)输出是一个4x4的矩阵1表示有边0表示无边。带权图的话直接把元素值从1改成对应的权重即可。你可能觉得这个知识点离日常应用很远但在做社交网络分析、路径规划、推荐系统的时候邻接矩阵就是数据的标准表达形式。numpy的优势在于矩阵运算极快你可以直接算邻接矩阵的平方来得到两步可达的路径数这在图算法里非常实用。当时学到这里我还搞混过一次numpy里写矩阵0可以用np.zeros但如果你用[0]*4去生成二维列表每一行其实是同一个对象的引用修改一个元素会连带修改整列。这个坑我记了很久今天也写出来提醒大家。5. 爬虫、协程与多任务向真实项目迈进5.1 一条爬虫的诞生从requests到解析Python爬虫几乎是每个学习者的必经之路。我入门的时候写了一个抓取翻译接口的小例子。“腾讯翻译”这个词条出现在热搜里说明很多人想用Python调用在线翻译的接口。腾讯翻译的公共接口有时会用到签名参数自己从头构造比较麻烦。个人练习的时候更推荐使用百度翻译的开放平台接口申请一个免费的key就可以调用。接口返回的是JSON结构化数据正好顺便练了json.loads。一个简要的实现思路是这样的import requests import json def translate(text, targeten): url https://api.example.com/translate payload { q: text, target: target, source: auto, token: your_token } resp requests.post(url, datapayload) data resp.json() return data[translated_text]结构化数据处理是爬虫的核心。网页返回的数据可能是HTML、JSON、XML你需要根据它的格式选择相应的解析方式。HTML用BeautifulSoup或者lxmlJSON直接json.loadsXML可以用xml.etree.ElementTree。学习爬虫的时候一定要记住爬虫本身不难难的是处理好反爬机制、编码问题和数据清洗。我这里建议你练习的时候务必遵守网站的robots.txt和服务条款只爬那些允许抓取的公开数据不要给别人的服务器添麻烦。5.2 协程与asyncio单线程也能并发Python的线程因为GIL全局解释器锁的存在在CPU密集型任务上并不能真正并行。但I/O密集型任务比如网络请求、读写文件协程就是非常高效的方案。我当时学协程的时候绕了很久才弄明白asyncio的运行模型。核心概念是事件循环。你可以把事件循环理解成一个调度员它管理着一堆“待办任务”当某个任务在等待I/O时调度员会切到另一个可以继续执行的任务。它没有让多个任务真正“同时”跑而是高效地利用等待时间。一个最简单的协程示例import asyncio async def fetch_data(name): print(f{name} start) await asyncio.sleep(1) print(f{name} end) async def main(): tasks [ asyncio.create_task(fetch_data(task1)), asyncio.create_task(fetch_data(task2)), ] await asyncio.gather(*tasks) asyncio.run(main())两个任务总共耗时1秒而不是2秒这就是协程的威力。await关键字的作用是“让出控制权”告诉事件循环我要等了你先去干别的。写异步代码的时候最容易犯的错误是忘记await导致协程对象被创建却没有真正执行打印出来是一堆coroutine object的地址而不是函数的输出。5.3 队列不堵塞先分清get和get_nowaitqueue.Queue是Python标准库里用来做线程间通信的数据结构。我搜过“python队列queue不堵塞”这个词条猜测很多人和我一样遇到的问题调用了queue.get()之后程序卡住不动了。原因很简单get()是阻塞式方法当队列为空时它会一直等待新元素进来。如果你不想让它傻等有两个选择一是设置超时参数queue.get(timeout3)等待3秒后抛Empty异常二是用queue.get_nowait()如果队列为空立刻抛queue.Empty异常你需要在外面try/except捕获import queue q queue.Queue() try: item q.get_nowait() except queue.Empty: print(队列为空不等待)这个模式在爬虫多线程采集时非常常用。多个生产者线程往队列里塞URL多个消费者线程从队列里取URL处理。当任务快要结束时消费者用get_nowait()作为退出判断能避免线程卡死在阻塞等待上。5.4 线程嵌套线程小心资源失控“python线程嵌套线程”这个搜索词我也很有共鸣。当时我的需求是主线程里跑一个任务队列每个任务内部还需要并发地请求多个接口也就是线程里再开线程。代码结构类似from concurrent.futures import ThreadPoolExecutor def inner_task(item): return item * 2 def outer_task(batch): with ThreadPoolExecutor(max_workers4) as executor: results list(executor.map(inner_task, batch)) return results with ThreadPoolExecutor(max_workers2) as outer_executor: batches [[1, 2, 3], [4, 5, 6]] for result in outer_executor.map(outer_task, batches): print(result)这种嵌套写法能跑通但有个我必须提醒的陷阱嵌套线程池很容易耗尽系统资源因为外层线程池的任务在等待内层线程池结果时外层线程本身没有释放如果任务数量特别大线程数会指数级膨胀。更稳妥的做法是用asyncio替代外层线程池或者把所有任务扁平化到一个线程池里。我个人现在写并发代码的原则是优先协程其次单层线程池嵌套线程能不用就不用。6. 趣味编程题与量化初探让代码解决真实问题6.1 李白打酒循环与递归的经典题目“李白打酒”是一道非常经典的算法题李白街上走提壶去打酒。遇店加一倍见花喝一斗。三遇店和花喝光壶中酒。试问壶中原有多少斗酒这道题看着像数学题其实是在训练循环倒推的思路。我们从最后一次遇花反推最后一次见花前壶里有1斗酒因为喝掉1斗后为0。倒推时要注意遇店前是遇店后的一半见花前是见花后的数量加1。写成程序就是一个从最后往前迭代的过程也可以用递归。我在练习时先写了一个循环版本再用函数递归实现了一遍两种写法让我对“从结果反推初始状态”有了更深的理解。这种题的意义不在题目本身而在于它逼着你把一个叙述性的场景翻译成精确的、可执行的逻辑。学编程本质上就是在学这种翻译能力。6.2 从邻接矩阵到图论用代码理解关系前面提到用numpy构建邻接矩阵这里再往前一步用Python的networkx库可以可视化整个图结构。看代码import networkx as nx import matplotlib.pyplot as plt G nx.Graph() G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)]) pos nx.spring_layout(G) nx.draw(G, pos, with_labelsTrue, node_colorlightblue) plt.savefig(graph.png, dpi200)物理布局、节点颜色、边权重这些可视化选项能把抽象的矩阵变成一眼能看懂的关系图。学到这里你会发现“数据结构”不再是课本上的名词矩阵、列表、字典、图它们都在用各自的方式描述现实世界的信息组织方式。6.3 量化交易策略双均线到底怎么跑搜索词里有“python量化交易策略代码”说明很多人对用Python炒股、做量化感兴趣。我必须先说一句量化交易不是稳赚的魔法策略本身只是一个决策规则收益和风险是高度不确定的。但作为学习项目写一个双均线策略回测是很不错的数据分析训练。双均线的逻辑很简单短期均线上穿长期均线时买入金叉下穿时卖出死叉。核心代码如下import pandas as pd df pd.read_csv(price_data.csv) df[short_ma] df[close].rolling(window5).mean() df[long_ma] df[close].rolling(window20).mean() df[signal] 0 df.loc[df[short_ma] df[long_ma], signal] 1 df[position] df[signal].diff()这个项目涵盖的知识点非常多pandas处理结构化数据、rolling计算滚动均值、diff计算信号变化、再结合matplotlib画出买卖点几乎把基础语法、数据结构、数据清洗、可视化的知识点全串起来了。即使你对金融没兴趣也推荐用类似方式找一个你关心的数据集做分析——只有亲手处理一份脏数据、完成一次完整的数据分析流程你才会真正理解Python的价值所在。7. 工具链与报错实录我替你们踩过的坑7.1 VSCode里的Python环境配置编辑器我推荐VSCode轻量、免费、插件丰富。装好Python插件之后有一个经常踩坑的环节选择解释器。按CtrlShiftP输入“Python: Select Interpreter”VSCode会列出当前系统找到的Python环境。如果你创建了虚拟环境一定要选择虚拟环境里的解释器否则你在终端pip install的库VSCode里运行时却提示找不到模块就是因为选错了解释器。虚拟环境就是每个项目独立的Python依赖环境。用venv创建python -m venv venv # Windows激活 venv\Scripts\activate # Linux/macOS激活 source venv/bin/activate我强烈建议新手从第二个项目开始就学会用虚拟环境。虽然多了一步激活操作但它能避免不同项目之间的库版本冲突。我当时在两个项目里分别用了不同版本的requests如果不隔离早就乱套了。7.2 安装报错0x80070643与winusb问题安装Python报错“0x80070643”是Windows系统常见的问题通常跟MSI安装程序或者系统更新相关。大致排查思路第一检查Windows Installer服务是否正常运行第二如果曾经装过Python但卸载不干净可以先用官方卸载工具彻底清理第三安装时右键安装包选择“以管理员身份运行”。如果还不行可能是系统更新组件异常导致的修改注册表或者使用命令行msiexec安装都是备选方案。另外一条搜索词“python winusb”也很有代表性。winusb是Windows系统的USB驱动模型如果你需要用Python操作USB设备比如读卡器、传感器、游戏手柄常见的做法是安装pyusb配合libusb。Windows下往往需要安装对应的USB驱动为WinUSB模式再通过pyusb访问设备。这个主题稍微进阶涉及不少底层知识但如果你正好有USB外设控制的兴趣可以往这个方向深入学习。提示一下pyusb是跨平台的Windows下的backend默认是libusb需要预先安装libusb的dll文件。7.3 ComfyUI的缺失节点包管理的一条经验搜索词“要安装缺失的节点请先在你的python环境中运行pip install -u --pre comfyui-m”这句话我推测是ComfyUI这类图形化工具在工作流加载时的报错提示。ComfyUI是一个基于节点式流程的图像生成工具当你下载别人的工作流之后经常会发现缺少自定义节点提示需要安装某个包。解决办法是在ComfyUI所在的Python环境中执行对应的pip命令。但这里有个细节非常重要必须要确认你执行pip时用的是ComfyUI对应的虚拟环境。很多人的做法是直接打开终端pip install结果包装到了全局环境里ComfyUI依然提示缺失。正确姿势是先在终端里激活ComfyUI的环境再执行pip install。如果你实在不熟悉虚拟环境也可以在ComfyUI的目录下找到它的python解释器完整路径直接用这个路径来运行pip。这个排查思路其实是通用的任何“我已经装了这个库却依然报错”的问题第一步要检查的就是——你安装的库是不是装到了你正在运行程序的同一个环境里。7.4 其他高频报错速查表下面整理几个我以及身边同学经常遇见的报错以后遇到可以直接对照排查。报错信息常见原因解决思路ModuleNotFoundError: No module named xxx库没有安装或者解释器环境不对pip install xxx检查当前解释器路径SyntaxError: invalid syntax语法错误常见是中文标点或漏了冒号找到报错行检查括号和标点TypeError: int object is not callable变量名覆盖了内置函数不要用sum、len这些内置名做变量名IndexError: list index out of range索引越界检查列表长度尤其是循环里的索引KeyError: xxx字典里没有这个键用dict.get(key, default)更安全FileNotFoundError文件路径不对使用绝对路径或os.path.join构造路径AttributeError: NoneType object has no attribute xxx函数返回了None还在调用它的方法检查前一步是否忘了return或解析失败PermissionError: [Errno 13]没有写入权限Linux下检查目录权限Windows下用管理员身份运行这些报错里的规律是相通的Python报错信息会告诉你错误类型和出错行不要看到红字就慌先读最后一行再往上看是哪一行代码触发九成问题都能定位。我学习Python三个月最深的感受是不要试图一口气把每个知识点都学“满”。编程是需要行动的知识你坐在那里看再多教程、收藏再多文章都不如自己动手写一段会报错的代码再把它修好来得有价值。3.14只是一个节点我的Python学习还会有很多个逗号、分号甚至反斜杠——但至少到现在为止这条路是越走越清楚的。如果你也是刚开始别怕报错报错才是学习真正开始的地方。