Python 3 基础速查
面向复习与日常开发的 Python 3 基础速查,涵盖核心语法、对象与类型、容器、函数、异常、模块和工程常识。
这是一份面向面试复习和日常开发的 Python 3 基础速查,重点整理名称绑定、可变对象、作用域、异常处理和环境隔离等高频易错点, 可按目录直接跳读。
版本:示例最低需要 Python 3.13,并按 Python 3.15 文档复核;实际项目以自身声明的 Python 版本为准。
1. Python、CPython 与交互环境
| 名称 | 定位 |
|---|---|
| Python | 语言及其规范 |
| CPython | 最常用、由 Python 项目维护的实现 |
| PyPy | 包含 JIT 的另一种实现,第三方扩展兼容性需要单独核对 |
| IPython、Jupyter | 交互环境,通常运行在 CPython 之上 |
将 Python 只概括为“解释型语言”并不准确。以默认 CPython 为例,源码会先编译为字节码,再由虚拟机执行,并可能缓存 .pyc;
具体执行方式取决于实现。Python 通常以一定运行时开销换取表达力、生态和开发效率,是否满足性能要求应以实测为准。
2. 安装、运行与环境隔离
尚未安装时,从 python.org 下载页 获取当前稳定版。新项目可以选择当前稳定版;加入已有项目时, 以项目声明的 Python 版本和依赖兼容范围为准。安装完成后先确认终端实际调用的是哪个版本。
2.1 确认解释器
macOS 或 Linux 通常使用 python3,Windows 可使用 py 启动器:
| |
直接运行解释器会进入 REPL,适合验证表达式;把代码保存为 hello.py 后则可以运行脚本:
| |
| |
2.2 每个项目使用独立虚拟环境
虚拟环境隔离解释器入口和第三方包,避免不同项目互相覆盖依赖。.venv 是可丢弃的本地产物,不应提交到 Git。
| |
激活后统一使用当前环境中的 python。用 python -m pip 比直接使用 pip 更明确,因为它能保证安装目标就是当前解释器:
| |
不要用 sudo pip install ... 修改系统 Python。项目依赖还应记录在 pyproject.toml 或锁文件中,虚拟环境本身则随时重建。
3. 语法、注释与命名
3.1 缩进是语法的一部分
Python 用缩进表示代码块。惯例是每层 4 个空格,不要混用 Tab 与空格;Tab 的显示宽度也不保证是 4 个空格。
| |
3.2 注释不等于文档字符串
# 开始的是单行注释。三引号创建的是字符串;当它出现在模块、类或函数开头时,才会成为可由工具读取的文档字符串。
因此,不应把三引号字符串笼统称为“多行注释”。
| |
注释应该解释“为什么”,而不是逐字复述代码。过时注释比没有注释更危险。
3.3 命名规则与惯例
标识符区分大小写,可以包含 Unicode 字母、数字和下划线,但不能以数字开头,也不能使用关键字。关键字应动态查看:
| |
Python 3.13 输出:
| |
常用的 PEP 8 命名约定:
- 变量、函数、模块:
snake_case - 类:
CapWords - 常量:
UPPER_CASE - 内部实现细节:前导下划线,如
_cache
全大写只是“不要重新赋值”的协作约定,不会让对象真正不可变。
4. 名称、对象与类型
4.1 赋值是名称绑定
Python 变量更准确的说法是“名称绑定到对象”,而不是一个固定类型的内存盒子:
| |
Python 是动态类型语言:名称可以重新绑定到不同类型的对象;同时它也是强类型语言,通常不会偷偷把无关类型混合运算:
| |
多个名称可以指向同一个可变对象:
| |
需要独立的浅拷贝可使用 first.copy() 或 first[:];嵌套对象是否也要复制,需要根据数据结构决定是否使用 copy.deepcopy()。
4.2 常见内置类型
| 类别 | 类型 | 是否可变 | 示例 |
|---|---|---|---|
| 空值 | NoneType | 否 | None |
| 布尔 | bool | 否 | True、False |
| 数值 | int、float、complex | 否 | 42、3.14、1+2j |
| 文本与字节 | str、bytes | 否 | "你好"、b"data" |
| 序列 | list、tuple、range | 仅 list 可变 | [1, 2]、(1, 2) |
| 映射 | dict | 是 | {"name": "Ada"} |
| 集合 | set、frozenset | 仅 set 可变 | {1, 2} |
“对象不可变”表示对象自身的值不能原地改变,不代表指向它的名称不能重新绑定。
4.3 == 与 is
== 比较值,is 比较是否为同一个对象。判断空值时使用 is None;不要依赖小整数或短字符串的缓存细节。
| |
4.4 真值规则
None、False、数值零以及空字符串和空容器通常为假,其余对象通常为真:
| |
if value: 同时把 0、空值和空容器视为假。如果业务上必须区分这些情况,就应写出精确条件。
5. 数值与运算符
常用算术运算符包括 +、-、*、/、//、% 和 **。/ 总是返回浮点数,// 是向负无穷取整的整除:
| |
int() 把浮点数向零截断,不等于数学上的向下取整:
| |
浮点数采用二进制表示,很多十进制小数不能精确存储。比较计算结果可使用 math.isclose();金额等十进制定点业务可使用
decimal.Decimal,并从字符串构造:
| |
比较运算可以链式书写,逻辑运算使用 and、or、not:
| |
6. 字符串、字节与格式化输出
6.1 字符串是不可变的 Unicode 文本
| |
切片遵循左闭右开区间 [start:stop:step]。字符串方法返回新对象,不会原地修改原字符串。
6.2 优先使用 f-string
% 格式化和 str.format() 仍然有效,但新代码通常优先使用可读性更好的 f-string:
| |
转义字符 \n 表示换行,\t 表示水平制表符;制表符显示成多宽由终端或编辑器决定。
| |
输出:
| |
6.3 文本与字节要显式转换
网络、压缩和二进制文件通常处理 bytes;界面和业务文本通常处理 str。二者不能直接拼接:
| |
编码是文本到字节,解码是字节到文本。读写文本文件时应明确指定编码。
7. 输入与安全转换
input() 总是返回字符串。转换可能失败,应处理具体的 ValueError:
| |
两种输入的执行结果:
| |
密码输入应使用 getpass.getpass(),不要回显后再打印:
| |
不要把 eval() 当成类型转换工具。它会执行 Python 表达式,对不可信输入使用可能导致任意代码执行。明确知道目标类型时,使用
int()、float()、str();结构化数据优先使用 JSON:
| |
处理只包含 Python 字面量的旧数据时可以评估 ast.literal_eval(),但仍应限制输入大小;跨系统交换数据时优先使用 JSON。
8. 核心容器
8.1 列表与元组
列表适合可变的有序数据,元组适合结构固定的记录或不可变序列:
| |
元组本身不能增删或替换元素,但元素仍可能指向列表等可变对象,因此元组不保证“深层不可变”,也不一定可哈希。
避免用乘法创建共享的嵌套可变对象:
| |
8.2 字典
字典保存键值映射,键必须可哈希。现代 Python 的字典保留插入顺序,但如果业务需要排序,仍应显式使用 sorted()。
| |
输出:
| |
mapping[key] 在键缺失时抛出 KeyError;mapping.get(key) 适合“缺失是正常情况”的读取。不要用 get() 掩盖本应存在的键。
8.3 集合
集合保存不重复、可哈希的元素,适合去重和成员判断;集合本身没有可依赖的展示顺序。
| |
8.4 推导式
推导式适合简短、单一的映射或过滤;逻辑复杂时使用普通循环更清楚。
| |
生成器表达式使用圆括号,按需产生值,不会一次构造完整列表:
| |
9. 分支、循环与模式匹配
9.1 if、for 与 while
Python 的 for 遍历可迭代对象,而不是只提供计数循环:
| |
输出:
| |
并行遍历多个序列可使用 zip():
| |
输出:
| |
strict=True 会在序列长度不一致时抛出 ValueError,适合长度必须相同的业务数据。
while 适合结束条件不是“遍历完某个集合”的情况。循环必须保证状态朝退出条件推进:
| |
输出:
| |
9.2 match 是结构化模式匹配
Python 3.10+ 的 match 不只是其他语言中 switch 的别名,它还能解构数据:
| |
简单的两三个条件通常继续使用 if 更直观;不要为了使用新语法而使用 match。
10. 函数与作用域
10.1 参数与返回值
函数可以组合位置参数、默认参数和仅限关键字参数:
| |
* 后的参数必须按关键字传递,可避免布尔值、数字等位置参数含义不清。*args 收集额外位置参数,**kwargs 收集额外关键字参数,
但普通业务函数不应无理由接受任意参数。
函数没有显式 return 时返回 None。返回多个值实际上是返回一个元组:
| |
10.2 不要使用可变默认值
默认参数在函数定义时求值,只创建一次:
| |
这个规则同样适用于字典、集合以及自定义的可变对象。
10.3 作用域与闭包
名称查找通常遵循 LEGB:局部(Local)、外层函数(Enclosing)、全局(Global)、内置(Built-in)。尽量通过参数和返回值传递数据, 少依赖可变全局状态。
| |
lambda 适合短小的单表达式函数,例如排序键;一旦需要分支、异常处理或文档,就应使用 def。
| |
11. 异常与资源管理
异常用于报告当前层不能正常完成的操作。捕获异常时应尽可能具体,不要用裸 except: 隐藏退出、取消和程序错误。
| |
异常结构的职责:
try:只包围可能失败的最小范围。except:处理明确知道如何恢复或转换的异常。else:仅在没有异常时执行。finally:无论是否异常都执行,适合必须进行的清理。
文件和锁等资源优先使用 with,由上下文管理器保证释放,通常无需手写 finally。假设 notes.txt 包含“第一行”和“第二行”:
| |
输出:
| |
数据库连接需要核对具体的上下文协议。例如,sqlite3.Connection 的 with 只管理事务提交或回滚,不会关闭连接,仍需显式调用
close() 或另外使用能负责关闭的上下文管理器。
不要通过“先读取失败,再新建文件”的宽泛异常逻辑判断文件是否存在。真正操作时应优先使用明确的打开模式并捕获具体异常;
Path.exists() 适合只需展示状态的场景,不能替代操作本身的错误处理。“先检查再操作”可能有并发竞态,真正的写入约束应由打开模式
或底层存储保证。
12. 文件、路径与结构化数据
12.1 使用 pathlib 表达路径
pathlib.Path 比手工拼接 / 或 \\ 更跨平台:
| |
输出如下,同时会生成 data/report.txt:
| |
read_text() 适合体积可控的文本;大文件应逐行读取,避免一次占用过多内存。
12.2 JSON 只支持有限的数据类型
| |
JSON 不会自动保存 datetime、Decimal、集合或自定义类,需要先转换为约定的数据结构。不要对不可信数据使用 pickle;反序列化
恶意 pickle 可以执行代码。
13. 模块、包与程序入口
每个 .py 文件都是模块。目录作为常规包时通常包含 __init__.py。导入模块会执行其顶层代码,因此模块顶层应以定义、常量和必要的
轻量初始化为主。
下面只是项目结构示意;可安装包还需要在 pyproject.toml 中声明构建和包发现配置:
| |
脚本入口使用显式的 main(),既方便测试,也避免模块被导入时直接执行业务:
| |
常见导入形式:
| |
避免 from module import *,它会让名称来源不清晰。模块名也不要取成 random.py、json.py、typing.py 等标准库名称,
否则可能遮蔽真正的模块。
14. 类与数据类
类把状态和行为组织在一起。不是所有数据都需要类:简单转换可用函数,固定的小型记录可考虑元组或数据类。
| |
@dataclass 可以生成初始化、相等性比较和展示等样板代码,但默认不会生成大小排序方法,也不会自动做业务校验。
继承表达“是一个”的关系,组合表达“拥有一个”的关系。业务代码通常优先组合,只有确实需要共享接口和可替换行为时再使用继承。
15. 迭代器与生成器
可迭代对象能产生迭代器,迭代器通过 __next__() 逐个返回值,耗尽时抛出 StopIteration。日常代码通常使用 for,无需手动调用这些方法。
包含 yield 的函数是生成器函数,调用后返回生成器对象,执行会在迭代时按需推进。假设 notes.txt 依次包含“第一行”、空行和
“第二行”:
| |
输出:
| |
生成器适合流式处理,但它通常只能消费一次,而且文件等资源的生命周期会随迭代过程延长。需要重复遍历时应重新创建生成器,或在数据量 允许时显式转成列表。
16. 类型标注
类型标注提高可读性,并帮助编辑器和静态类型检查器发现问题;Python 运行时不会根据类型注解强制检查它们。
| |
这里的 type 别名语句来自 Python 3.12,因此适用于本文最低 Python 3.13 的基线。现代代码可直接写 list[str]、dict[str, int],
可空类型写成
User | None。类型别名不是新的运行时类型,UserId 仍然是 int;若业务需要区分不同标识符,必须另行设计。类型标注应表达真实契约,
不要为了“全部有类型”而使用大量 Any 或复杂泛型。
如果运行时确实需要验证外部输入,仍应写解析与校验逻辑;静态类型检查不能替代边界校验。
17. 并发模型怎么选
先按任务性质选择模型,再做性能测试:
| 场景 | 常见选择 | 主要注意点 |
|---|---|---|
| 大量阻塞 I/O,已有同步库 | threading、ThreadPoolExecutor | 共享状态、锁、超时和取消 |
| 大量并发网络 I/O,调用链支持异步 | asyncio | 不要在事件循环中执行阻塞操作 |
| 默认启用 GIL 的 CPython 中,CPU 密集型纯 Python 计算 | multiprocessing、ProcessPoolExecutor | 进程启动、序列化和内存成本 |
| 向量计算、科学计算 | NumPy 等原生实现 | 数据布局和库自身的线程策略 |
不要把“并发”与“并行”等同,也不要默认线程越多越快。共享可变状态会引入竞态;即使某个操作在当前 CPython 中看似原子,也不应把实现 细节当成业务同步协议。
Python 3.13 首次提供实验性的 free-threaded CPython 构建,可在关闭 GIL 的模式下运行线程;它不是普通 3.13 解释器的默认行为,C 扩展 兼容性和性能都需要测试。3.13 的 JIT 同样是实验能力,构建时才启用且默认关闭。二者都不是“升级后程序自动并行、自动变快”。
版本状态随后继续演进:从 3.14 起 free-threaded 构建获得官方支持,但仍是可选模式;到 3.15,JIT 仍是实验功能且默认关闭。
18. 调试、日志与测试
18.1 先读完整 traceback
traceback 最后一行给出异常类型和消息,上方调用栈说明错误如何到达现场。修复根因,不要只在最外层加一个宽泛的 try/except。
常见异常包括:
SyntaxError:语法无法解析。IndentationError:缩进不合法。NameError:名称不存在。TypeError:操作或调用不接受当前类型。ValueError:类型可以接受,但值不合法。KeyError、IndexError:映射键或序列位置不存在。FileNotFoundError:目标文件不存在。
临时观察变量可以使用 print(),交互调试可使用 breakpoint();长期运行程序应使用 logging,而不是散落的调试输出:
| |
18.2 为行为写测试
标准库 unittest 可以直接起步,项目也可以选择第三方测试框架。测试应覆盖公开行为、边界和失败路径,而不是绑定内部实现细节。
把下面内容保存为 test_example.py:
| |
| |
示例输出(unittest 默认写入 stderr,耗时因环境而异):
| |
19. Python 3.13 带来了什么
对基础学习最直观的变化是 Windows 及支持 curses 的类 Unix 终端默认使用新的交互式解释器:支持多行编辑和历史记录,
终端提示与 traceback 默认着色,错误提示也继续改进。
需要准确区分的 3.13 能力:
- free-threaded CPython:实验性的可选构建,不是默认解释器“移除了 GIL”。
- JIT:实验性、构建时选择、默认关闭;3.13 时性能收益仍有限。
- 类型系统:类型参数支持默认值,新增
TypeIs、ReadOnly等能力,主要服务静态类型工具。 - 标准库清理:
cgi、imghdr、telnetlib等一批长期弃用模块被移除,升级旧项目应先查看移植说明。 locals()语义明确化:调试器和动态执行工具更容易获得一致行为,普通入门代码不应依赖修改locals()。
这些变化不会改写前面介绍的核心语法。升级项目时应运行测试、检查依赖支持范围,并阅读对应版本的 What’s New 与移植说明,不能只修改 版本号后假定兼容。
20. 一个可继续扩展的小程序
下面的命令行程序综合了路径、函数、类型标注、容器、异常和标准库。它逐行读取 UTF-8 文本,统计由英文字母和内部单引号组成的单词; 中文等没有空格边界的语言需要真正的分词工具,不能直接套用这个正则表达式:
| |
将程序保存为 word_count.py,并令 sample.txt 内容为 Python is simple. Python is readable.:
| |
输出:
| |
继续练习时可以逐步加入 argparse 参数、停用词、JSON 输出和单元测试。每次只增加一个可验证的能力,比一次堆入框架更容易理解。
21. 学完基础后检查什么
- 能解释名称绑定、可变对象以及
==/is的差异。 - 能为字符串、数值和结构化输入选择安全的转换方式,不对外部输入使用
eval()。 - 能熟练使用列表、字典、集合、推导式、
enumerate()和zip()。 - 能写参数清晰的函数,避免可变默认值,并理解局部与外层作用域。
- 能捕获具体异常,用
with管理文件等资源。 - 能创建虚拟环境,通过
python -m pip管理当前项目依赖。 - 能把代码拆成模块,使用
main()入口,并为关键行为编写测试。 - 能按 I/O 密集或 CPU 密集选择并发模型,不把实验性 free-threaded/JIT 当成默认加速。
评论
使用 GitHub 登录后参与讨论,评论将公开保存在 GitHub。
站长管理删除会同步到 GitHub,无法撤销。
阅读到这里时加载评论。