Python环境配置指南
管理Python版本
推荐使用 https://github.com/pyenv/pyenv 来管理不同版本的python,但是它不支持windows,如果你使用windows,请使用 https://github.com/pyenv-win/pyenv-win 。
如果你需要使用特定版本的python,先安装它,类似于
1 | pyenv install 3.9.6 |
随后在项目的根目录,使用
1 | pyenv local 3.9.6 |
它会生成一个配置文件 .python-version
,就会让进入项目根目录,就会自动切换到3.9.6的版本。
管理虚拟环境
Poetry 适合现代 Python 项目开发、个人或小型团队开发、需要发布到 PyPI 的项目。
特点:
- 自动化依赖管理:Poetry 能够自动处理依赖冲突,生成 pyproject.toml 和 poetry.lock 文件,确保依赖一致性。
- 内置虚拟环境管理:Poetry 会自动为每个项目创建虚拟环境,隔离项目依赖,保证项目间的互不干扰。
- 简化的发布流程:通过 poetry build 和 poetry publish,可以轻松地将 Python 包发布到 PyPI。
- 现代化设计:Poetry 支持 pyproject.toml,这是 Python 最新的标准配置文件格式。
优点:
- 统一的依赖管理和虚拟环境管理,操作简单。
- 自动解决依赖冲突,生成锁定文件,保证不同环境依赖的一致性。
- 提供项目的创建、构建、依赖管理、测试和发布的全流程工具。
- pyproject.toml 文件非常清晰,方便配置。
1 | poetry new my_project # 创建新项目 |
Poetry对当前的python解释器有依赖。当你使用 Poetry 创建虚拟环境时,它会检查系统中当前使用的 Python 版本是否符合项目中的版本要求。如果当前系统或环境中的 Python 版本不符合 pyproject.toml 中的规定,Poetry 会提示错误,阻止虚拟环境的创建或依赖安装。报错类似 Poetry could not find a compatible version of python for your project.
为了弥补 Poetry 不能直接管理 Python 版本的缺点,你可以结合 pyenv 这类工具来一起使用。
以上pyenv会自动切换环境,这样就没有问题了。
相比conda,poetry 专注于依赖管理和包管理,适合纯 Python 项目。Conda 创建的虚拟环境是完全隔离的,每个环境可以有不同的 Python 版本和不同的依赖包,管理起来非常方便。
但是Conda在一些科学计算库上,有预编译的版本(如 numpy, scipy, pandas),Conda 可以直接安装预编译好的版本,避免本地编译的复杂性。尤其在windows平台,能解决许多依赖包编译失败的问题。
关于macOS(darwin)系统,它确实在用户体验上下了功夫,并且有类unix的系统。但是它的编译工具链,依赖库等生态,还是不如linux,尤其是需要自行编译的部分,比如部分python的包,就会容易遇到各种bug,需要手动解决,再加上arm架构,会进一步造成一些兼容性问题。
包的开发
Python 包的开发是一项重要的技能,可以帮助你组织代码、实现代码复用,并且将功能模块分发给其他开发者使用。
包和模块是什么
在 Python 中,一个包(Package)就是一个包含多个模块的目录,其中通过 __init__.py
文件来表明它是一个包。包允许你将代码逻辑分解为多个文件,并且通过模块的方式进行导入和复用。
- 模块:一个 Python 文件(*.py 文件)就是一个模块。模块可以包含函数、类和变量。
- 包:包是包含多个模块的文件夹。包使得模块之间可以被组织起来,以便更好的管理。
目录结构示例:
1 | my_package/ |
在代码中使用包(如果要供外部使用,推荐使用相对路径):
1 | # 导入包中的模块 |
一个典型的python 包的格式
1 | my_package/ |
setup.py
和 pyproject.toml
必须存在一个,用于说明包如何安装,后者更加先进,建议使用。
开发测试
本地测试的时候,应该在包内使用相对路径,并且以“可编辑模式”安装到虚拟环境中。这会在虚拟环境或全局环境中创建一个符号链接,指向包的源代码目录,修改源代码会立即生效。
1 | pip install -e . |
单元测试:
1 | # tests/test_module1.py |
还有简单的测试,文件以 _test.py
结尾,然后函数以 test_
开头,依赖pytest。
安装包
下面是一个传统的pyproject的定义,[build-system]
里这两者一般都不用变动。
- requires 指定了构建项目所需的工具和版本。在这个例子中,你需要 setuptools 版本 >= 61.0 来进行包的构建。
- build-backend 指定了构建后端,这里使用的是 setuptools 的构建元数据模块 setuptools.build_meta。
[project]
是核心的配置参数
- requires-python:表明 Python 版本的要求,这里要求 Python >= 3.9。
- classifiers:这些是 Python 包的元数据,用于描述包的兼容性、用途和许可证等。
- dependencies:列出了包的依赖项,当其他人安装此包时,这些依赖项也会被自动安装。
[tool.setuptools.packages.find]
告诉 setuptools 如何找到包。这里它会从当前目录中找到所有以 sgp 开头的包。
1 | [build-system] |
对于poetry工具,需要另外一套配置,则把元信息,运行时依赖依赖和开发时的依赖,构建系统都写的比较清楚。poetry build
的效果和 python -m build
类似,会在 dist/ 目录下生成两种类型的分发文件:
- Source distribution (sdist):一个 .tar.gz 文件,用于源代码分发。
- Wheel (bdist_wheel):一个 .whl 文件,这是已编译的、便于安装的包格式。
1 | [tool.poetry] |
而且 poetry install
不仅会安装好依赖,还会执行了类似 pip install -e .
的功能,执行了可编辑模式安装。
代码编译分发
上一小节介绍了如何打包,并且介绍了2种打包生成的文件。。
1 | dist/ |
这里两种分发包都是可以安装的 pip install dist/my_package-0.1.0-py3-none-any.whl
和 pip install dist/my_package-0.1.0.tar.gz
安装源代码分发包时,pip 会从源代码构建包,这通常涉及到编译步骤。如果项目中有 C 扩展或其他需要编译的代码,安装时会需要构建工具(如 gcc、make 等)来编译这些部分。这种方式兼容性好。但是构建时如果出问题,需要使用者具备比较深入的知识。如果你的项目包含 C 扩展或其他需要编译的代码,源代码分发包是必不可少的。
.whl
文件是一种标准的 Python 二进制包格式,它是预编译好的包。包含编译后的文件,并且已经处理好所有依赖,因此安装时不需要再次编译。Wheel 包通常包括预编译的 C 扩展、二进制文件以及纯 Python 文件。安装速度快,不用编译,但是是平台和架构相关的,需要编译多个版本。
发布的时候,使用 twine upload dist/*
。