知其然,知其所以然
Python 2026-09-29

sys.path:模块搜索路径是怎么生成的

本机真实验证 sys.path[0] 在 python 脚本 / -c / -m / 符号链接 / -P 下分别是什么;列出完整 sys.path 每一项来源;脚本目录里的 random.py 会遮蔽标准库(randint(1,100) 返回 4),json.py 里 import json 得到带改名建议的 AttributeError,os.py 因为已导入而无法遮蔽;300 次「先失败再创建再导入」在本机 0 次未找到。

Python CPython 导入系统 真实验证 动画演示
Python 2026-09-29

importlib:如何动态导入和重载模块

本机真实验证 importlib:reload 之后模块对象 id 不变但 from 导入的旧值不更新、旧类的实例不再是新类的实例、已删除的名字残留;spec_from_file_location 能加载带连字符的文件且不进 sys.modules;find_spec 只查找不导入;LazyLoader 让 lazy() 返回 0.38 ms,首次访问属性才花 310 ms 执行模块。

Python 标准库 导入系统 真实验证 动画演示
Python 2026-09-29

__main__:脚本运行和模块运行有什么区别

本机真实对同一个文件分别用 python 文件 / python -m / import 三种方式运行:__name__、__package__、__spec__、sys.path[0] 和相对导入是否可用各不相同;a.py 与 b.py 互相导入会让 a.py 的顶层代码执行两次;定义在 __main__ 里的类 pickle 后在别处读取报 AttributeError;macOS 默认 spawn 下缺少 __main__ 保护会报 RuntimeError。

Python CPython 模块 真实验证 动画演示
Python 2026-09-29

Python 进程退出:正常返回、异常和强制终止有什么区别

本机真实用 10 种方式结束一个 Python 进程,记录 atexit、finally、__del__ 和缓冲 print 是否执行:正常返回、异常、sys.exit、子线程异常、SIGINT、带 handler 的 SIGTERM 都执行,而 os._exit、os.abort、默认 SIGTERM、SIGKILL 全部不执行;SIGINT 的进程最终以信号 2 而不是退出码结束。

Python CPython 进程 信号 真实验证 动画演示
Python 2026-09-29

CPython free-threading:去掉 GIL 后会改变什么

本机用 3.14 与自由线程版 3.14t 各跑同一个 CPU 密集任务:4 线程并行时 GIL 版加速比 1.00x、自由线程版 2.61x(8 线程 3.66x),设 PYTHON_GIL=1 后回到 1.23x;4 个线程各做 50 万次 += 1,GIL 版恒为 2000000,自由线程版只得到约 83 万。

Python CPython 并发 GIL 真实验证 动画演示
Python 2026-09-29

子解释器:多个 Python 解释器如何隔离

本机 Python 3.14 的 concurrent.interpreters 真实实验:子解释器的全局变量和 sys.modules 相互独立;Lock、文件不能跨解释器传,主脚本里定义的类也传不过去;4 份 CPU 密集任务下 InterpreterPoolExecutor 加速 2.86x、线程池 1.01x、进程池 2.22x;创建一个子解释器 8.7 ms,spawn 一个进程 48 ms。

Python CPython 并发 子解释器 真实验证 动画演示
Python 2026-09-29

ctypes:Python 如何调用 C 动态库

本机真实用 ctypes 调用 libc 与自己编译的 C 动态库:不声明 argtypes 时传 Python float 直接 ArgumentError,只声明 argtypes 不声明 restype 时 sqrt(2.0) 返回 0;malloc 默认返回值被截断成 32 位;结构体布局与 C 的 sizeof/offsetof 一致(24 字节);qsort 回调 Python 比较函数 17 次;对 100 万整数求和,C 函数 0.30 ms、sum() 3.0 ms、for 循环 53 ms;读空指针进程直接被 SIGSEGV 杀死。

Python 标准库 C扩展 ctypes 真实验证 动画演示
Python 2026-09-29

Python 构建系统:pyproject.toml 到底由谁执行

本机真实用一个自己写的最小 build backend(通过 backend-path 放在项目里,requires 为空)验证 pyproject.toml 的构建流程:python -m build 与 pip 作为前端,每个钩子都在一个独立的后端子进程里执行(pid 各不相同,父进程是前端),默认隔离环境使用临时 build-env 的 Python;pip 比 build 多调用 prepare_metadata_for_build_wheel;产出的 wheel 只是含 dist-info 的 zip。

Python 打包 PEP 517 真实验证 动画演示
Python 2026-09-29

Python entry points:命令行和插件是如何被发现的

本机在全新虚拟环境里真实安装一个项目:pip 把 [project.scripts] 变成 env/bin/hello-cli 几行启动脚本,把 entry-points 写进 dist-info/entry_points.txt;importlib.metadata.entry_points() 只读元数据、不导入代码,load() 才导入;手工放一个假 dist-info 就能「发现」不存在的插件;扫描成本随已安装包数增长(0 → 1600 个:3.5 → 70 ms)。

Python 打包 插件 真实验证 动画演示
Python 2026-09-29

editable install:pip install -e 到底改变了什么

本机在全新虚拟环境里对比普通安装与 pip install -e:普通安装拷贝一份代码、改源码不生效;可编辑安装只在 site-packages 放一个 __editable__ .pth(内容是项目 src 路径)和带 editable:true 的 direct_url.json,改源码立即生效、新增包也能 import;但新增命令行脚本必须重新安装;并用真实的 setuptools 后端复验同样结果。

Python 打包 pip 真实验证 动画演示
Python 2026-09-29

unittest discovery:测试框架如何找到 TestCase

本机造一棵测试目录树,真实验证 unittest discover 的规则:只导入文件名匹配 test*.py 的模块(strings_test.py、check_util.py 被忽略);没有 __init__.py 的子目录整个被跳过而且没有任何提示;导入失败的测试文件变成 _FailedTest 报 ERROR 而发现继续;只收集继承 TestCase 且以 test 开头的方法,同一个类里按方法名字母序执行;-k 过滤时导入失败仍会被报告。

Python 测试 unittest 真实验证 动画演示
Python 2026-09-29

pytest 参数化:一组测试如何覆盖几十种输入

本机 pytest 9.1.1 真实验证 @pytest.mark.parametrize:10 组参数生成 10 个独立用例,2 个失败都被精确报告(for 循环写法只报第一个);默认 id 对非基本类型退化为 x4、x5;叠加两个 parametrize 得到 3×4=12 的笛卡尔积;共享的可变参数在用例间是同一个对象;3000 个参数化用例总耗时 1.02 s、单个用例循环 0.30 s。

Python 测试 pytest 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号