"Python很简单"——这句话可能是初学者最大的误导。Python的语法确实简洁,但简洁不等于容易。用好这门语言需要理解的远不止语法本身:数据类型的内存模型、作用域链的执行规则、迭代器与生成器的惰性求值机制、装饰器背后的闭包原理……这些才是区分"会写"和"会用"的分水岭。
本文从零基础视角出发,以120天的学习周期为轴线,系统覆盖了从环境搭建到工程实践的全链路。核心观点很简单:学Python不是背语法,是建立一套"把问题拆解为数据+流程+边界条件"的思维框架。技术细节和常见陷阱逐项穿透,每个概念都有可运行的代码佐证。
第一章 出发之前:认识Python
1.1 Python到底是个什么东西
从技术角度讲,Python是一门解释型、动态类型、垃圾回收、面向对象的通用编程语言。但从学习角度讲,你只需要记住三件事:
第一,Python是一门翻译着运行的语言。 你把代码写进一个.py文件,然后告诉Python解释器"把这个文件读一遍,然后执行"。解释器一边读一边翻译成机器能懂的东西,一边跑。这就是"解释型语言"的含义——与之相对的是C语言那种要等全部编译完才能跑的"编译型语言"。解释型的优点是写起来快、改起来也快;缺点是跑起来比C慢。对初学者来说,快跑不如快写。
第二,Python的类型是在运行时决定的。 你不需要写int x = 5,直接写x = 5就行——Python会在运行时自动判断x这个变量是个整数。这叫"动态类型",是Python"简单"的重要来源。但动态类型的好处也是代价:你写x = 5之后又写x = "hello",Python不会报错,而且这种错误可能在代码跑了几万行之后才暴露出来。类型安全是你要用编码习惯来弥补的事情。
第三,Python的设计哲学是一件事最好只有一种做法。 Python之禅(在交互环境输入import this能看到全文)里有一句:"There should be one—and preferably only one—obvious way to do it."这对初学者非常友好——你不用像在Perl里那样学会十种写循环的方法后再去判断哪种最好。但它的反面意思是:如果你发现自己的写法"不太Pythonic",那大概率是你的写法有问题,而不是Python的限制。
1.2 为什么选Python
TIobe指数在2024-2026年间持续将Python排在第一名,Stack Overflow 2025年开发者调查中Python是使用量增长最快的语言之一[论文转载]。但这和你没关系——工业界的排名不应该决定你的学习选择。
真正应该选Python的原因只有一个:你想做的那件事,Python能帮你做得最快。
想处理Excel表格和数据分析?Pandas + NumPy。想写一个小工具挂到网上?Flask + FastAPI。想用摄像头识别图像?OpenCV Python绑定。想批量下载网页内容?requests + BeautifulSoup。机器学习和深度学习?那基本上默认就是Python。在这些领域,Python的第三方库生态是其他语言无法替代的。
Python的劣势也很明确:不适合做底层系统、不适合做实时高并发、不适合移动端。 如果你是想写操作系统内核或者Unity3D游戏脚本——Python不是答案。
第二章 学习前的认知升级:别让"简单"骗了你
2.1 四条铁律
在我接触过的数百名Python初学者中,进步最快的那些人在第一天就建立了以下四种认知。建议你在敲第一行代码之前先接受它们。
铁律一:编程不是在背答案,是"输入→处理→输出"的游戏。 任何程序都可以拆分为三块:从哪里拿数据(输入)、对数据做了什么变换(处理)、结果输出到哪里(输出)。变量赋值、条件判断、循环、函数调用——这四个东西覆盖了初学者阶段95%的"处理"逻辑。别被"编程"这个词吓到,它本质上就是一个信息处理的流水线。
铁律二:每天20分钟 > 周末6小时。 编程是一种程序性记忆(procedural memory),和学乐器、学开车一样。练得越勤,脑子里的"模式"越稳固。连续五天每天写20分钟代码的人,进步速度远超周末集中写6小时的人。这个规律在多个编程教育研究中被反复验证[论文转载]。把Python学习做成每天的习惯,而不是周末的任务。
铁律三:读代码的能力等于写代码的能力。 如果你看不懂别人写的一小段代码——不是指不懂那个业务逻辑,而是不理解"为什么这个列表推导式写在这里""为什么用了生成器而不是列表"——那你自己写的时候大概率会绕远路。大量阅读优秀代码(标准库源码、知名开源项目的代码片段)是进阶的唯一捷径。
铁律四:不要和报错敌对。 Python的报错信息(Traceback)在主流编程语言中属于最友好的一档——它会告诉你第几行出了问题、是什么类型的错误、以及可能的原因。大多数新手的问题根本不是"不会解决",而是"看到红色文字就慌了,没仔细读报错内容"。你遇到的90%的报错在过去二十年里已经被上亿人次踩过,Stack Overflow上一定有答案。 养成看到报错先粘贴最后一行进搜索引擎的习惯。
2.2 三个必须破除的误解
误解一:学Python要背库。 Python标准库有200多个模块,第三方库超过40万个。没人背得完。你需要做的是学会查文档——dir()函数可以列出模块里有什么、help()可以输出帮助文档、PEP 8规定了命名规范让你一看名字就知道这个函数大概干什么。记住"我要找什么"比记住"哪里有"重要得多。
误解二:不学透基础就不能动手。 很多人在"变量和数据类型"上磨了两个月,以为要把所有数据类型的内存模型搞清楚才开始写项目。事实是:学完变量、数据类型、条件判断、循环、函数这五个东西,你就可以开始写真正的程序了——哪怕只是猜数字游戏、待办事项清单。其他知识(类、装饰器、异常处理)可以在项目中"遇到一个问题解决一个问题"地学习,效率远高于先全部学完再动手。
误解三:复制粘贴学不会编程。 这个说法很流行,但反直觉的是:手工逐字键入每一行代码的"学习方法"同样是低效的。 真正的高效方法是在理解逻辑的前提下,先读通代码,再手写一段相似但不完全相同的代码来巩固理解。把别人的代码段复制进自己的项目然后改参数、加功能——这才是工业界的真实做法。区别在于:你是在理解的基础上复制,还是为了应付作业而复制。
第三章 环境搭建:第一天的工程习惯决定了三个月的上限
3.1 Python解释器安装
访问python.org,下载最新稳定版(Python 3.13.x)。安装时有两个关键步骤:
- 勾选"Add Python to PATH"——不勾选的话,你之后在命令行里敲
python会报"command not found"[实测数据](这是Stack Overflow上Python新手提问率最高的三个问题之一)。 - 安装自带的pip(Python包管理器)保留默认勾选。
安装完成后,打开命令行(Windows按Win+R→输入cmd回车,或者更推荐装Windows Terminal),分别输入:
python --version # 确认版本号pip --version # 确认pip可用
如果你看到类似Python 3.13.x的输出,说明环境已经就绪。
3.2 IDE选择:推荐链
新手阶段最合适的编辑器进化链:
VS Code(推荐起点)→ PyCharm(中型项目)→ 随意(你已经有自己的偏好了)
VS Code的安装配置要点:
- 去code.visualstudio.com下载并安装
- 安装Python扩展(微软官方出品,扩展名是Python)
- 开启setting中的"Format on Save"——每次保存自动格式化代码,这能让你在第一天就养成PEP 8编码规范的肌肉记忆
一个反直觉的建议:不要在第一天花超过30分钟配置编辑器。 很多新手"学编程的第一天"变成了"配置Vim主题和插件的八小时"。VS Code开箱即用,能写能跑就够了。花里胡哨的环境配置不会让你的Python水平进步一丁点。
3.3 虚拟环境:第一天就该养成的习惯
虚拟环境是Python项目隔离依赖的机制。用个例子解释你就懂了:项目A需要Flask 2.0,项目B需要Flask 3.0。你不用虚拟环境——全局安装一个版本,总有一个项目冲突。你用了虚拟环境——每个项目有自己的"小房间",互不干扰。
创建和使用虚拟环境的三行命令:
python -m venv venvvenv\Scripts\activatesource venv/bin/activate
激活后命令行前面会出现(venv)字样,表示你已经在虚拟环境中。在虚拟环境里用pip install安装的所有包,只会留在这个环境的文件夹里,不会污染全局。
新手常犯的错误:不建虚拟环境,直接pip install XXX。等你同时装了几个库出现依赖冲突——依赖降级、版本不兼容——到时候再来排查,已经晚了。从第一个项目开始就养成习惯:先建虚拟环境,再装依赖。
第四章 基础语法速通:五个核心概念
以下五个概念在初学者阶段覆盖了95%的代码逻辑。不建议按顺序"学完一个再学下一个",它们是互相穿插的——你在学循环的时候会用函数、在学函数的时候会用到条件判断。理解了关系后就大胆跳。
4.1 变量与数据类型
Python的变量本质是"标签"——变量名贴在某个内存对象上。x = 5在内存中做了三件事:①创建整数对象5;②创建变量名x;③把x贴到5这个对象上。当你执行x = 10,Python不是把5改成10(整数是不可变对象),而是新建一个10的对象,然后把x标签撕下来贴到10上。
这个机制解释了Python中的"可变"和"不可变":
| | | |
|---|
| int, float, str, bool, tuple | | x = 5 | |
| | lst.append(1) | 这也意味着当多个变量引用同一个list时,一个改了全部都会受影响 |
新手最常掉进去的坑是a = b = [],然后对a操作后发现b也变了——原因就是a和b贴在了同一个list对象上。
基础数据类型速览代码示例:
age = 25price = 19.99result = 10 / 3 # 结果是 3.333... (浮点数除法,注意不是3)name = "Python"greeting = 'Hello'multi_line = """这是多行字符串"""substring = name[0:3] # "Pyt"(切片操作,左闭右开)is_active = Trueis_done = Falsenothing = None # None在Python中有特殊含义,不等于False、0或空字符串print(type(name)) # <class 'str'>print(isinstance(age, int)) # True
运行一下这段代码,确保每行的输出都在你的预期范围内,然后继续。
4.2 条件判断与循环
Python的条件判断没有括号(不需要if (x > 5)),用冒号和缩进表示代码块:
score = 85if score >= 90: grade = "A"elif score >= 80: grade = "B"elif score >= 70: grade = "C"else: grade = "D"print(f"成绩等级:{grade}") # 输出 "成绩等级:B"
注意这里的elif——很多从其他语言转过来的同学会写成else if,在Python里那是语法错误。
循环有两个:for(遍历可迭代对象)和while(条件控制)。在初学者阶段,for的使用频率远高于while,重点掌握它:
fruits = ["苹果", "香蕉", "橘子"]for fruit in fruits: print(f"我喜欢吃{fruit}")for i in range(5): # range(5) → 0,1,2,3,4 print(i)for i in range(2, 8, 2): # range(2, 8, 2) → 2,4,6 print(i)for idx, fruit in enumerate(fruits): print(f"第{idx + 1}个水果是{fruit}")
练习: 写一个从1加到100的程序(答案是用for循环和range)。如果5分钟还没写出来,说明上面的内容还需要再看一遍。
4.3 数据结构:四件套
列表、元组、字典、集合——这四样东西在Python中的地位相当于汉字里的偏旁部首。你写的每一个Python程序都在用它们。
列表(list):可变的有序序列,用方括号。
students = ["张三", "李四", "王五"]students.append("赵六") # 追加students.insert(1, "钱七") # 插入到索引1的位置students.remove("王五") # 删除第一个匹配的元素popped = students.pop() # 弹出并返回最后一个元素sliced = students[1:3] # 切片:取索引1到3(不包含3)
元组(tuple):不可变的有序序列,用圆括号。适合放"不应修改的"数据。
coordinates = (116.4, 39.9) # 经纬度lon, lat = coordinates # 解包
字典(dict):键值对映射,用花括号。Python使用最为高频的数据结构之一。
student = { "name": "张三", "age": 20, "courses": ["数学", "Python"]}print(student["name"]) # "张三"student["grade"] = "A" # 新增键值对student["age"] = 21 # 修改已有键的值print(student.get("score", "N/A")) # "N/A"(安全取值,键不存在时返回默认值)for key, value in student.items(): # 遍历字典 print(f"{key}: {value}")
集合(set):不重复的无序集合,用花括号(但和字典不同,没有冒号)。
tags = {"Python", "编程", "学习"}tags.add("入门")numbers = [1, 2, 2, 3, 3, 3]unique = set(numbers) # {1, 2, 3}a = {1, 2, 3}b = {2, 3, 4}print(a & b) # 交集:{2, 3}print(a | b) # 并集:{1, 2, 3, 4}print(a - b) # 差集:{1}
练习题(检验理解): 创建一个字典,每个键是一个人名,每个值是一个三元组(年龄、城市、职业),然后遍历这个字典,打印出"X岁住在Y的Z"。
4.4 函数
函数是"给一段逻辑起个名字"。你不需要一次学完所有关于函数的知识(参数默认值、*args、**kwargs、装饰器、闭包),先把最基本的搞懂:
def greet(name, greeting="你好"): """向指定的人打招呼""" # 文档字符串,养成写的习惯 return f"{greeting},{name}!"message = greet("小明")print(message) # "你好,小明!"message = greet("小红", "早上好")print(message) # "早上好,小红!"
函数的返回值不是必须的——不写return的函数默认返回None。
在这个阶段,理解"函数是对象"这件事很重要——因为在Python里函数不只是一段可以调用的代码,它本身也是一个可以赋值、传参的对象:
def add(a, b): return a + bdef apply(func, x, y): return func(x, y)result = apply(add, 3, 5) # 8——函数作为参数传递
理解这件事对你之后学装饰器(decorator)很关键——装饰器本质上就是"一个接受函数作为参数、返回新函数的高阶函数"。
练习: 写一个函数is_palindrome(s),判断一个字符串是不是回文(正读反读一样)。进阶:忽略空格和大小写。
4.5 文件操作
学完前面四个概念后,你应该能写一些"在终端运行、输入输出都是文本"的小程序了。第五个概念让你能真正把你的程序和数据做持久化:
with open("notes.txt", "w", encoding="utf-8") as f: f.write("第一行内容\n") f.write("第二行内容\n")with open("notes.txt", "r", encoding="utf-8") as f: content = f.read() # 读全部 lines = f.readlines() # 逐行读到列表(上面一行已经读到末尾了,这里重新打开)with open("notes.txt", "r") as f: for line in f: # 逐行迭代(最常用的方式,内存友好) print(line.strip())
with语句是Python的上下文管理器——它会自动帮你关闭文件。这比你手动调用f.close()安全得多(即使中间抛出异常也会正确关闭)。
第五章 进阶基础:从"会写"到"会用好"
当你能不查文档写出"读取一个CSV文件、计算平均值、输出结果"的程序时,基础语法阶段就基本通关了。接下来进入"真正常用但需要理解"的内容。
5.1 列表推导式与生成器表达式
列表推导式是Python的标志性语法。熟悉之后你会觉得写一段普通的for循环"太啰嗦了"——但这个熟悉过程需要时间,不要着急。
squares = []for i in range(10): squares.append(i ** 2)squares = [i ** 2 for i in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]even_squares = [i ** 2 for i in range(10) if i % 2 == 0] # [0, 4, 16, 36, 64]square_dict = {i: i ** 2 for i in range(5)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 4}
生成器表达式和列表推导式的语法几乎一样,但用小括号而不是方括号:
squares_list = [i ** 2 for i in range(1000000)] # 吃内存,100万个整数squares_gen = (i ** 2 for i in range(1000000)) # 几乎不占内存for val in squares_gen: if val > 100: break print(val)
当数据量很大时(比如10万条以上的记录),优先用生成器表达式,否则代码会吃掉大量内存,而这在生产环境中意味着程序崩溃。
5.2 装饰器
装饰器(decorator)是初学者阶段最"劝退"的概念之一。它的本质很简单:装饰器是一个函数,它接受另一个函数作为参数,然后返回一个增强版的新函数。
先看一个最基础的手写实现:
import timedef timer(func): """测量函数执行时间的装饰器""" def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.__name__} 耗时 {end - start:.4f} 秒") return result return wrapper@timerdef slow_function(): total = 0 for i in range(10_000_000): total += i return totalslow_function() # 输出类似:slow_function 耗时 0.2845 秒
对初学者来说,装饰器不需要你写,但你需要能看懂。你在实际项目中遇到@app.route('/')和@cache.memoize()就是在使用别人写好的装饰器。
5.3 异常处理
一个程序从不会按照你设想的完美路径运行。文件可能打不开、用户可能输入非法字符、网络可能断掉。异常处理就是为这些情况准备的:
def divide(a, b): try: result = a / b except ZeroDivisionError: print("错误:除数不能为零") return None except TypeError: print("错误:请传入数字") return None else: print(f"计算完成,结果是{result}") return result finally: print("计算过程结束")divide(10, 2) # 正常执行divide(10, 0) # 捕获除零异常
异常处理不是让代码"不出错"——它是在错误发生后有尊严地处理错误,而不是让程序直接崩溃。不要滥用try...except: pass——那是把报告器静音了,问题还在。
5.4 模块与包管理
随着代码变多,你不能把所有代码写在一个文件里。模块就是一个.py文件,包就是包含__init__.py的文件夹。
def say_hello(name): return f"Hello, {name}!"import my_moduleprint(my_module.say_hello("Python")) # "Hello, Python!"from my_module import say_helloprint(say_hello("Python"))import numpy as np # 所有人都这么写,你也要习惯
包管理使用pip,你用的所有第三方库都通过它安装:
pip install requests # 安装最新版pip install pandas==2.0.0 # 安装指定版本pip install -r requirements.txt # 从文件批量安装
第六章 六个必须上手的实战项目
学完上面的内容,你已经掌握了Python的核心语法和常用模式。真正的学习从现在开始——把代码从读进去变成写出来。
新手阶段最推荐的项目序列。按难度递增排列,每个项目解决你之前学过的概念中80%的知识点。
项目1:交互式计算器(第1周)
覆盖知识点:变量、数据类型、条件判断、循环、函数、异常处理
要求:
扩展:添加异常处理的完整覆盖,添加历史记录功能(把每次计算存到一个列表里,输入"history"时显示)。
项目2:个人知识笔记系统(第2-3周)
通过这个项目,你会真正理解文件I/O和数据结构在"有意义的程序"中是怎么配合的。
核心功能:
- 添加笔记(标题 + 内容 + 标签,存入字典列表)
涉及的库:json(标准库)、pathlib(标准库)
import jsonnotes = [ {"title": "Python列表推导式", "content": "基本语法:[表达式 for 变量 in 迭代器]", "tags": ["Python", "基础"]},]with open("notes.json", "w", encoding="utf-8") as f: json.dump(notes, f, ensure_ascii=False, indent=2)with open("notes.json", "r", encoding="utf-8") as f: loaded = json.load(f)
项目3:命令行天气预报(第3-4周)
目标:调用公开API获取数据,学会HTTP请求和JSON解析——这几乎是所有现代程序的核心交互方式。
涉及的库:requests(第三方)、datetime(标准库)
import requestsdef get_weather(city): url = f"https://wttr.in/{city}?format=%C+%t" response = requests.get(url) if response.status_code == 200: return response.text else: return "查询失败"print(get_weather("Beijing"))
扩展:解析更详细的JSON数据,用argparse库让程序接受命令行参数(python weather.py --city Shanghai --days 3)。
项目4:简易应用(第4-5周)
核心功能:
技能点:类与对象、文件I/O、日期时间处理、命令行交互
from dataclasses import dataclassfrom datetime import datetime@dataclassclass Task: title: str priority: str = "中" created_at: datetime = None completed: bool = False def __post_init__(self): if self.created_at is None: self.created_at = datetime.now()
使用dataclass装饰器是Python 3.7+的最佳实践,比手写__init__和__repr__简洁得多。
项目5:网页爬虫入门(第5-6周)
目标:从目标网页抓取结构化信息。这个项目能让你深刻理解"数据从哪里来"这个问题。
涉及的库:requests + BeautifulSoup4
import requestsfrom bs4 import BeautifulSoupurl = "https://news.ycombinator.com/"response = requests.get(url)soup = BeautifulSoup(response.text, "html.parser")titles = soup.select(".titleline > a")for i, title in enumerate(titles[:10], 1): print(f"{i}. {title.text}")
注意伦理:爬虫不等于滥采。请务必遵守目标网站的robots.txt、设置合理的请求间隔(time.sleep(1))、不要对他人服务器造成压力。
项目6:数据分析看板(第6-8周)
目标:从公开数据集(Kaggle、天池、Gov Open Data)下载一份CSV数据,用pandas读取、清洗、分析,然后用matplotlib可视化。
涉及的库:pandas + matplotlib
import pandas as pdimport matplotlib.pyplot as pltdf = pd.read_csv("sales_data.csv")print(df.head()) # 看前5行print(df.describe()) # 基本统计量df = df.dropna(subset=["price"]) # 删除价格为空的行df["date"] = pd.to_datetime(df["date"]) # 日期字段规范化monthly = df.resample("ME", on="date")["price"].sum()monthly.plot(kind="line", title="月度销售额趋势")plt.ylabel("销售额(元)")plt.tight_layout()plt.savefig("monthly_sales.png")plt.show()
这个项目做完后,你应该能够独立找一份数据集、完成从读取到可视化输出的全流程。这是一个合格的Python初级工程师应该具备的核心能力。
第七章 新手最容易踩的十个坑
以下十个错误是Python初学者反复踩的。每个都附带了正确的编码模式。
坑1:可变对象作函数默认参数
def add_student(student, roster=[]): roster.append(student) return rosterprint(add_student("小明")) # ['小明']print(add_student("小红")) # ['小明', '小红'] — 不等于预期!
原因:函数默认参数在定义时就被求值和创建,而不是每次调用时创建。所有调用共享同一个列表对象。
正确做法:
def add_student(student, roster=None): if roster is None: roster = [] roster.append(student) return roster
坑2:修改遍历中的列表
items = [1, 2, 3, 4, 5]for item in items: if item % 2 == 0: items.remove(item) # ❌ 遍历过程中修改列表print(items) # 结果是 [1, 3, 5]?不对,是 [1, 3, 5]——这里刚好碰对了,但在更复杂的场景下一定会出错
正确做法:创建新列表或复制后遍历
items = [1, 2, 3, 4, 5]items = [item for item in items if item % 2 != 0] # 列表推导式创建新列表for item in items.copy(): if item % 2 == 0: items.remove(item)
坑3:混用Tab和空格
Python 3不允许混用。在所有IDE中设置"Tab = 4个空格",然后只用空格。这能让你避免Python社区中最容易诊断也最容易让新手崩溃的错误。
坑4:误用==和is
a = [1, 2, 3]b = [1, 2, 3]print(a == b) # True(值相等)print(a is b) # False(不是同一个对象)
==比较值,is比较身份(内存地址)。除了None的检测(x is None),其他场景几乎都应该用==。
坑5:浅拷贝与深拷贝
original = [1, [2, 3], 4]copied = original.copy() # 浅拷贝copied[1].append(5)print(original) # [1, [2, 3, 5], 4] — 被改了!import copydeep = copy.deepcopy(original) # 深拷贝deep[1].append(6)print(original[1]) # [2, 3, 5] — 没有被影响
当数据结构中包含可变对象时,默认的拷贝方式(.copy()、切片、list())都是浅拷贝。如果你需要完全独立的副本,使用copy.deepcopy()。所有dict中有嵌套list的场景都要注意这个问题。
坑6:列表推导式写成了生成器表达式
squares = [x ** 2 for x in range(10)] # squares 是 listsquares = (x ** 2 for x in range(10)) # squares 是 generator
语法上的差异只有方括号和圆括号的区别,但行为完全不同。前一个一次性创建所有元素,后一个惰性求值。
坑7:误以为+=对不可变对象是原地修改
s = "Hello"t = ss += " World"print(t) # "Hello" —— s改了,t不受影响
字符串是不可变对象,+=创建了新字符串对象并将s绑定过去。但t仍然指着原来那个字符串。
坑8:不处理文件编码
with open("data.csv") as f: # 默认使用系统编码,Windows上是GBK data = f.read() # 遇到中文大概率报错with open("data.csv", encoding="utf-8") as f: # 明确指定UTF-8 data = f.read()
坑9:用except:捕获所有异常
try: result = risky_operation()except: # ❌ 捕获了包括KeyboardInterrupt在内的所有异常 pass # 导致Ctrl+C都无法中断程序try: result = risky_operation()except Exception as e: # ✅ 只捕获Exception及其子类 print(f"出错:{e}")
永远不要用空的except:。至少指定except Exception。更精确地指定具体的异常类型(ValueError、FileNotFoundError等)是最佳实践。
坑10:全局变量滥用
在函数内部修改全局变量时,必须声明global。不声明的话,Python会把同名的局部变量当做一个新变量:
counter = 0def increment(): global counter # 不加这行会报错 counter += 1
更推荐的做法:尽量不要在函数内部依赖全局变量。把全局变量改为函数参数传递或使用类属性。
第八章 持续进阶路线图
基础通关之后,下一步的选择取决于你的目标方向。以下是三个主流方向的进阶路径:
数据科学/分析方向
- 第8-12周:pandas进阶(MultiIndex、groupby、merge、pivot_table)、数据清洗方法论
- 第12-16周:matplotlib + seaborn数据可视化、统计学基础(假设检验、回归分析)
- 第16-20周:scikit-learn基础(分类、回归、聚类)、模型评估(交叉验证、混淆矩阵)
- 第20周+:SQL基础、Kaggle实战、项目输出
Web开发方向
- 第8-12周:Flask框架(路由、模板、表单、数据库ORM)
- 第12-16周:HTML/CSS/JavaScript基础 + RESTful API设计
- 第16-20周:Django/ FastAPI进阶、用户认证系统、部署(Docker + Nginx)
- 第20周+:前端框架(Vue/React基础)、CI/CD管道
自动化/工具方向
- 第8-12周:路径操作(pathlib)、正则表达式(re模块)、smtplib发送邮件
- 第12-16周:Excel自动化(openpyxl)、PDF处理(PyMuPDF / reportlab)
- 第16-20周:Selenium自动化测试、定时任务(APScheduler)
- 第20周+:CLI工具打包(Click / argparse)、发布到PyPI
每个阶段都应该坚持的习惯
1. 每天提交一次代码到GitHub。 哪怕只是加了一个函数,也要保持提交习惯。这不只是版本控制——这是你向未来的雇主证明"我真的每天都在写代码"的最直接证据。你的GitHub提交日历(那个小绿格子图)比任何简历都好使。
2. 每周读三个Python标准库模块的文档。 标准库(random, datetime, collections, itertools, functools, pathlib)覆盖了你在日常开发中90%的"通用"需求。标准库出品的代码质量和文档质量远高于大多数第三方库,读它们是在学习Python的最佳实践。
3. 学会在Stack Overflow上搜问题和提问。 你遇到的99%的报错,在过去五年内都有人踩过且有人给出了正确答案。把报错信息的最后3-5行复制粘贴到搜索引擎,这是每个Python开发者每天都会做的事情。没什么不好意思的。
4. 从第2周开始就用好REPL环境。 Python的交互式环境(REPL,你直接在终端输入python后进入的那个>>>提示符)是你最好的调试助手。对某个表达式不确定结果?直接输进去验证。不需要写一个完整的脚本然后运行来看。Jupyter Notebook是更现代化的REPL替代品,推荐作为日常探索式编程的工具。
结语
学Python是一件可以三个月上手、需要三年精通的事。十二周的路线图不是让你成为专家的承诺——它是让你成为"能独立完成一个完整项目"的承诺。这个差距,是"写得了代码"和"能交付结果"之间的差距。
文章最后,给你一个检验自己在120天后是否合格的里程碑任务(Capstone Project):
写一个程序,每天定时从公开API抓取某个城市(自选)的天气数据,存储到SQLite数据库,每周自动生成一份包含趋势图的PDF报告,并通过电子邮件发送给你自己。
如果这个任务你能独立完成,你就从"学过Python"进入了"会用Python解决真实问题"的阶段。后者的世界里需要有太多东西要学,但你已经有基础了。
参考文献
- Python Software Foundation (2026). The Python Tutorial. Python 3.13 Documentation.
- Lutz, M. (2013). Learning Python, 5th Edition. O'Reilly Media.
- Slatkin, B. (2019). Effective Python: 90 Specific Ways to Write Better Python, 2nd Edition. Addison-Wesley Professional.
- McKinney, W. (2022). Python for Data Analysis, 3rd Edition. O'Reilly Media.
- Matthes, E. (2023). Python Crash Course, 3rd Edition. No Starch Press.
- Ramalho, L. (2022). Fluent Python, 2nd Edition. O'Reilly Media.
- Stack Overflow (2025). Developer Survey Results 2025.
- TIOBE Software (2026). TIOBE Index for Python. TIOBE.com.
- Sweigart, A. (2019). Automate the Boring Stuff with Python, 2nd Edition. No Starch Press.
注:本公众号文章仅用作分享交流,版权与观点均属原创作者。如有错漏或侵犯您的权益,联系我们进行更正或删除。