1 清理 PIP 缓存
# Credits: https://linuxhandbook.com/clear-pip-cache/
pip cache info # 查看缓存信息
pip cache list # 查找各个包的缓存
pip cache dir # 查找缓存所在的目录
pip cache remove [package_name] # 从缓存中删除特定包
pip cache remove * # 从缓存中删除每个包
pip cache purge # 从 pip 缓存中删除所有内容
sudo rm -rf /root/.cache/pip # 手动删除 pip 缓存
pip install package_name --no-cache-dir # 安装没有缓存的包
2 查看Python库的空间占用
结果示例(部分):
xgboost 2.0.1: 436.63 MB
----------------------------------------
catboost 1.2.2: 298.30 MB
----------------------------------------
httpstan 4.10.1: 214.71 MB
----------------------------------------
llvmlite 0.41.1: 134.52 MB
----------------------------------------
scipy 1.11.3: 96.34 MB
相关代码:
# Credits: https://stackoverflow.com/a/67914559/11067496
sort_in_descending = True # Show packages in descending order
import os
import pkg_resources
from tqdm import tqdm
def calc_container(path):
total_size = 0
for dirpath, _, filenames in os.walk(path):
for f in filenames:
fp = os.path.join(dirpath, f)
total_size += os.path.getsize(fp)
return total_size
dists = [d for d in pkg_resources.working_set]
dists_with_size = {}
for dist in tqdm(dists):
try:
path = os.path.join(dist.location, dist.project_name)
size = calc_container(path)
dists_with_size[size] = dist
except OSError:
'{} no longer exists'.format(dist.project_name)
# Sort packages size
dists_with_size = dict(sorted(dists_with_size.items(), reverse=sort_in_descending))
for size, dist in dists_with_size.items():
if size/1000 > 1.0:
print (f"{dist}: {size/1000000:.2f} MB")
print("-"*40)
3 模块依赖分析
自带工具:pip freeze
- 支持已有安装模块的依赖分析
- 支持直接输出
requirements.txt
第三方分析工具:<code>pipdeptree</code>
- 支持已有安装模块的依赖分析(输出格式更人性化)
- 支持直接输出
requirements.txt
(还支持其他格式) - 支持单个已安装模块的上层依赖分析
- 分析警告:冲突依赖项和循环依赖
4 终端调试代码
pdb:Python自带的Debug工具
非侵入式:python3 -m pdb filename.py
侵入式:import pdb;pdb.set_trace()
pdb 常用命令:
l
:查看当前位置前后11行源代码ll
:查看当前函数或框架的所有源代码b
:查看或设置断点(b lineno;b filename:lineno; b functionname
)tbreak
:添加临时断点(执行一次后自动删除断点;方法同b
)cl
:清除断点,多个断点以空格为间隔p
:打印变量值s
:执行下一行(能够进入函数体)n
:执行下一行(不会进入函数体)r
:执行下一行(在函数中时会直接执行到函数返回处)c
:持续执行下去,直到遇到一个断点unt lineno
:持续执行下去,直到达到指定行或遇到一个断点interact
:启动交互式解释器w
: 打印堆栈信息- 跳到堆栈上一层:
u
;跳到堆栈下一层:d
q
:退出
更多用法:pdb --- Python 的调试器
5 单文件调试
判断当前运行的是主程序还是被导入的模块:
def foo():
print("foo() from module.py")
if __name__ == '__main__':
print("module.py is being run directly")
else:
print("module.py is being imported into another module")
- 模块化和复用:单个 Python 文件既可以被导入使用,也可以独立运行
- 测试用例:文件作为主程序运行时执行,不影响作为模块导入的情况
- 代码清晰:可以清晰区分模块的接口和实现,方便代码理解和维护
6 全局解释器 GIL
GIL 被称为全局解释器锁(Global Interpreter Lock),是 Python 虚拟机上用作互斥线程的一种机制,它的作用是保证任何情况下虚拟机中只会有一个线程被运行,而其他线程都处于等待 GIL 锁被释放的状态。
GIL 的优点
- 提高单线程程序的执行速度
- 更易于集成 c 扩展模块
GIL 的缺点:
- 无法充分利用多核多进程与多线程
- 多线程资源共享,可能遇到线程安全问题(即同一时刻,必须保证只有一个线程对共享资源进行修改;加锁就是一种同步机制来保证线程安全)
Python 提供了其他方式可以绕过 GIL 的局限,比如使用多进程multiprocess 模块或者采用 C 语言扩展的方式,以及通过 ctypes 和 C 动态库来充分利用物理内核的计算能力。
7 优化导包顺序
安装: pip install usort
执行: usort format main.py
优化后的顺序:标准库>第三方库>自定义库或相对引用库
8 自定义模块的安装
python setup.py
作为命令行工具在 setuptools (版本 58.3.0)中已被弃用
Deprecated 已弃用 | Recommendation 推荐 |
---|---|
python setup.py install |
python -m pip install . |
python setup.py develop |
python -m pip install --editable . |
python setup.py sdist |
python -m build |
python setup.py bdist_wheel |
python -m build |
注意:
python -m build
命令需要配合build
模块使用