Skip to content

Commit 52ec833

Browse files
📝 更新Python文档,增强内容与示例
- 修正了文档中的拼写错误,确保术语的一致性与准确性。 - 增加了对动态链接库的说明,明确了`.so`和`.dll`的定义及使用。 - 优化了模块导入部分的描述,提升了对Python模块查找顺序的理解。 - 更新了垃圾回收机制的解释,详细说明了引用计数的工作原理。 - 增加了关于第三方库安装的详细步骤,提供了更清晰的使用指导。 - 引入了符号链接的概念,解释了其在开发过程中的优势。 - 更新了关于`PYTHONPATH`的说明,强调了其在包管理中的重要性。
1 parent 3309bb3 commit 52ec833

File tree

1 file changed

+95
-16
lines changed

1 file changed

+95
-16
lines changed

docs/docs/选择编程语言/Python/39模块.mdx

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ python的`import`不止能导入`.py`后缀结尾的文件
3535

3636
Python的`import`通过`importlib`模块自动处理这些不同格式的文件。
3737

38-
`.so``.dll`分别是Linux和window的动态链接库,可使用 `ctypes` 模块导入。
38+
`.so``.dll`分别是Linux和Windows的动态链接库,可使用 `ctypes` 模块导入。
3939

4040
`.pyx`是Cython的源代码文件,支持Python与C代码混合编程。可以将 `.pyx` 文件编译为纯 C 文件,但需要注意的是,这个 C 文件通常是用来创建一个 Python 扩展模块 的,它不能独立运行。需要进一步编译为 `.so``.dll``.pyd` 文件。
4141

@@ -91,7 +91,7 @@ if __name__ == "__main__":
9191

9292
通常情况下,当使用 import 语句导入模块后,Python 会按照以下顺序查找指定的模块文件:
9393

94-
> 前目录,即当前执行的程序文件所在目录下查找;
94+
> 当前目录,即当前执行的程序文件所在目录下查找;
9595
9696
> 到 PYTHONPATH(环境变量)下的每个目录中查找;
9797
@@ -108,7 +108,7 @@ if __name__ == "__main__":
108108
> 设置 path 系统环境变量。
109109
110110

111-
具体区别可以创建下面的文件解构来了解
111+
具体区别可以创建下面的文件结构来了解
112112

113113
```bash
114114
top/
@@ -177,7 +177,7 @@ from .second_copy import *
177177

178178
### 垃圾回收机制
179179

180-
如果持续不断加载数据,调用函数模块,计算机的内存会溢出,Python 的垃圾回收机制。是计数机制,当一个对象的引用数为 0 时,它就会被垃圾回收机制回收。
180+
如果持续不断加载数据,调用函数模块,计算机的内存会溢出,Python 的垃圾回收机制采用引用计数机制,当一个对象的引用数为 0 时,它就会被垃圾回收机制回收。
181181

182182
```python
183183
import sys
@@ -204,8 +204,8 @@ del b # 删除变量b:b对应的对象的引用计数器-1 (此时计数
204204
del a # 删除变量a:a对应的对象的引用计数器-1 (此时引用计数器为0)
205205

206206
# 当引用计数器为0 时,意味着没有人再使用这个对象,这个对象就变成垃圾,垃圾回收。
207-
# 回收:1.对象从refchain的链表移除。
208-
#.将对象进行销毁,内存归还给操作系统,可用内存就增加。
207+
# 回收:1. 对象从refchain的链表移除。
208+
# 2. 将对象进行销毁,内存归还给操作系统,可用内存就增加。
209209
sys.getrefcount(a)
210210
```
211211

@@ -235,18 +235,21 @@ print(math.sqrt(16)) # 4.0
235235

236236
优秀的第三方库有很多,例如[awesome-python](https://awesome-python.com/)中列举了大量优秀的第三方库。
237237

238+
### 安装
239+
238240
这里第三方模块使用的基本流程 以 opencv 为例
239241

240242
- 下载 `pip install opencv-python`
241243
- 导入 `import cv2`
242-
- 使用 模块名.方法名 示例 : `cv2.imread('./img/cat.jpg')`
244+
- 使用 `模块名.方法名` 示例 : `cv2.imread('cat.jpg')`
243245

244246
这里需要注意的是:opencv 模块的下载名、导入名均不是 opencv,opencv 共有4种不同的下载名:`opencv-python``opencv-python-headless``opencv-contrib-python``opencv-contrib-python-headless`
245247

246248
事实上,模块名、下载名与导入名更多是开发者出于习惯会将名称统一,并非一种强制的规则。建议在下载模块之前先通过搜索引擎搜索。
247249

248-
对于复杂的模块来说,使用 help()方法、dir()方法不能很好的满足我们的需求。如果是新手需要搭配官方文档,查阅使用实例。
250+
对于复杂的模块来说,使用 help()方法、dir()方法不能很好的满足我们的需求。需要搭配官方文档,查阅使用实例。
249251

252+
:::info
250253
第三方模块与系统模块一样,都是自定义好的一系列模块,这些模块也自然存在一些版本差异。
251254

252255
在使用的过程之中很可能因为版本的不匹配、方法的弃用导致示例的代码失效。
@@ -255,6 +258,80 @@ print(math.sqrt(16)) # 4.0
255258

256259
- 安装指定的版本示例: `pip install opencv-python==x.x.x` (x.x.x为版本号)
257260
- 升级至最新版本示例: `pip install --upgrade opencv-python`
261+
:::
262+
263+
此外,有些包作者会仅在`GitHub`提供源码,需要我们自己编译安装。
264+
265+
`uv pip install .` 使用uv安装当前目录下的包。并以<Highlight>拷贝的方式</Highlight>将其添加到 `site-packages` 中。
266+
267+
`uv pip install -e .` 使用uv安装当前目录下的包,并以<Highlight color="g">符号链接</Highlight>的方式将其添加到 `site-packages` 中。
268+
269+
两种方式都会搜索当前项目下的`pyproject.toml``setup.py`。如果同时存在只会使用`pyproject.toml`
270+
271+
:::info
272+
在开发过程中会频繁的修改代码并导入测试,传统的方式是每次修改代码后,都需要重新构建包、重新安装包。不优雅。
273+
274+
符号链接(Symbolic Link)是一种文件系统对象,它指向另一个文件或目录的位置。当你访问符号链接时,操作系统会自动将符号链接解析为实际的目标文件或目录(软链接)。
275+
276+
这让我们可以在实际的目录中修改代码,另一边立刻能看到修改后的效果。不需要每次修改都重新构建、安装包。
277+
:::
278+
279+
在Linux服务器中安装包安装到全局还是用户目录下需要根据实际情况选择。
280+
281+
- 如果需要安装到系统环境,可以使用`--break-system-packages`后缀,例如:`pip install --break-system-packages requests`
282+
283+
- 如果需要安装到用户目录下,可以使用`--user`后缀,例如:`pip install --user requests`
284+
285+
:::info
286+
在现代 Linux 发行版中, 系统 Python 标记为 “外部管理环境”(externally managed environment)。
287+
288+
由 操作系统的包管理器(如 apt)统一维护,禁止用户通过 `pip`(即使是 `--user`)直接安装包,以防破坏系统依赖。
289+
290+
如果你要安装的是`uv``ruff`这样的<Highlight color="g">可执行应用程序</Highlight>,推荐使用`pipx`独立安装。
291+
292+
```bash showLineNumbers
293+
sudo apt install pipx
294+
pipx install uv
295+
pipx install ruff
296+
```
297+
298+
如果你要安装的是`requests``opencv`这样的<Highlight color="g">Python包</Highlight>,推荐使用虚拟环境结合`pip`独立安装。
299+
```bash showLineNumbers
300+
python3 -m venv .venv
301+
source .venv/bin/activate
302+
pip install requests
303+
```
304+
305+
对于更加特殊的一些包,如`ros2`会使用到特定的Python包(`rclpy`等),`ros2`会将其下载到本地目录后,将这个目录添加到`PYTHONPATH`环境变量中。让所有Python解释器找包时都能加载这个目录内的模块。
306+
307+
- `PYTHONPATH` 是一个操作系统级别的环境变量,用于指定Python解释器的搜索路径。
308+
- `PYTHONPATH` 的值是一个或多个目录路径,优先级高于标准库和 `site-packages`
309+
- `PYTHONPATH` 只是额外添加的搜索路径,为空时不会影响默认的搜索路径。
310+
- 除了`PYTHONPATH`环境变量,还有`PATH`等环境变量会影响Python解释器的搜索路径。你可以通过`env`命令查看当前所有设置的环境变量。
311+
312+
不过这种方式也增加了包冲突的风险,我们个人开发时使用虚拟环境管理包。
313+
:::
314+
315+
更多子命令与参数可以查看[pip官方文档](https://pip.pypa.io/en/stable/)
316+
317+
| 命令 | 作用说明 |
318+
|------------------|---------|
319+
| `pip install` | 安装 Python 包(来自 PyPI、本地文件、VCS 等) |
320+
| `pip uninstall` | 卸载已安装的包 |
321+
| `pip inspect` | 以结构化 JSON 格式输出当前环境的包信息(实验性,较新版本支持) |
322+
| `pip list` | 列出当前环境中所有已安装的包及其版本 |
323+
| `pip show` | 显示某个已安装包的详细信息(如版本、作者、依赖、位置等) |
324+
| `pip freeze` |`requirements.txt` 兼容格式输出已安装包列表(常用于锁定依赖) |
325+
| `pip check` | 验证已安装包的依赖是否满足,检测版本冲突 |
326+
| `pip lock` | 生成可复现的依赖锁文件(截至 pip v25.2,此命令尚未正式实现,处于规划/实验阶段) |
327+
| `pip download` | 下载包及其依赖(不安装),用于离线环境或缓存 |
328+
| `pip wheel` | 将包构建为 wheel 格式的分发文件(`.whl`|
329+
| `pip hash` | 计算并输出文件的哈希值(用于验证包完整性) |
330+
| `pip search` | **已弃用**:原用于在 PyPI 上搜索包,因 API 关闭已不可用 |
331+
| `pip index` | 查询包在索引(如 PyPI)中的元数据(如版本、兼容性等) |
332+
| `pip cache` | 管理 pip 的本地缓存(查看、清空等) |
333+
| `pip config` | 管理 pip 的配置文件(设置镜像源、超时等) |
334+
| `pip debug` | 显示 pip 的调试信息(如兼容标签、环境路径、版本等) |
258335

259336
### 运行时与安装时视图
260337

@@ -274,9 +351,7 @@ import requests
274351

275352
那么,包是怎么出现在 `sys.path` 里的?
276353

277-
答案是:`pip install requests`
278-
279-
pip 做了什么?
354+
答案是:`pip install requests`。pip 做了:
280355

281356
1. **下载**:从 PyPI 下载 `requests` 的 wheel 包。
282357
2. **解压**:把包内容解压到 `site-packages` 目录。
@@ -287,7 +362,9 @@ pip 做了什么?
287362
当我们在命令行执行 `pip install requests` 时,pip 实际上会向 PyPI(Python Package Index)发送一系列 HTTP 请求来查找、下载和验证包。
288363

289364
pip 首先会向 PyPI 发送一个 GET 请求,以获取包的元数据信息,例如版本号、依赖关系等。
290-
```
365+
366+
```bash showLineNumbers
367+
# 下载请求示例
291368
GET /pypi/requests/json HTTP/1.1
292369
Host: pypi.org
293370
User-Agent: pip/21.0.1
@@ -297,7 +374,9 @@ Connection: keep-alive
297374
```
298375

299376
一旦 pip 获取了包的元数据,它会根据元数据中的下载链接发送另一个 GET 请求来下载包文件(通常是 wheel 文件或源码包)。
300-
```
377+
378+
```bash showLineNumbers
379+
# 下载请求示例
301380
GET /packages/66/49/7b6c842e994f9353296cb2865fc206635286b27415336348f39/requests-2.25.1-py2.py3-none-any.whl HTTP/1.1
302381
Host: files.pythonhosted.org
303382
User-Agent: pip/21.0.1
@@ -311,7 +390,7 @@ Connection: keep-alive
311390
:::info
312391
你可以提前获得包的wheel压缩文件,例如`requests-2.32.5-py3-none-any.whl`
313392

314-
它通常在 `PYPI` 侧边`Download files`,记得选择适配你Python与计算平台版本的压缩文件。
393+
`PYPI`每个包的侧边栏`Download files`中可能会有多个版本的压缩文件,记得选择适配你Python与计算平台版本的压缩文件。
315394

316395
那么你就可以通过`pip install requests-2.32.5-py3-none-any.whl`安装它,等价于跳过了前面的网络通信下载时间。
317396
:::
@@ -345,7 +424,7 @@ pip 会记录详细的日志信息,包括请求的 URL、响应状态码、下
345424

346425
没有这个身份证,pip 就不知道这个包是谁、从哪来、依赖谁、能不能卸载。
347426

348-
当你执行 `pip list``pip show requests`,看到的信息,全都来自这个 `.dist-info`
427+
当你执行 `pip list``pip show requests`,看到的信息,全都来自这个 `.dist-info`
349428

350429
### 离线安装
351430

@@ -380,7 +459,7 @@ Python 包管理,管的是模块与解释器的关系,是包与依赖的关
380459

381460
我们安装的模块来自于`pypi.org`,我们也可以分享我们的模块到`pypi.org`
382461

383-
截至2025年8月,UV 已经成为最现代化和高效的 Python 包管理工具,它集成了包管理、虚拟环境和打包发布功能,比传统的 pip + setuptools 方案更快更简单。
462+
截至2025年10月,UV 已经成为最现代化和高效的 Python 包管理工具,它集成了包管理、虚拟环境和打包发布功能,比传统的 pip + setuptools 方案更快更简单。
384463

385464
### 目录结构
386465

0 commit comments

Comments
 (0)