为什么要在本地创建虚拟环境
个人经历
我在刚学Python的时候,并没有创建虚拟环境。所有包都是全局下载。
可当我需要把Python代码部署到服务器的时候,问题就出现了。
因为在服务器上,我们也需要运行pip
或者conda
来下载项目中所使用的包。
那么如何知道项目中使用了哪些包呢?
可以运行如下命令:
# pip的命令
pip freeze > requirements.txt
# conda的命令
conda env export > environment.yml
把这个项目中使用到的包信息都放在requirements.txt
或者environment.yml
。
我得到的environment.yml
文件内容如下
name: base
channels:
- conda-forge
- defaults
- https://repo.anaconda.com/pkgs/main
- https://repo.anaconda.com/pkgs/r
dependencies:
- anaconda-anon-usage=0.5.0=py312hfb7c958_100
- annotated-types=0.6.0=py312hecd8cb5_0
- archspec=0.2.3=pyhd3eb1b0_0
- asgiref=3.8.1=pyhd8ed1ab_1
- black=24.10.0=py312hecd8cb5_0
- blas=1.0=openblas
- boltons=24.1.0=py312hecd8cb5_0
- bottleneck=1.4.2=py312ha2b695f_0
- brotli-python=1.0.9=py312h6d0c2b6_9
- bzip2=1.0.8=h6c40b1e_6
- c-ares=1.19.1=h6c40b1e_0
- ca-certificates=2025.4.26=hbd8a1cb_0
- certifi=2025.4.26=py312hecd8cb5_0
- cffi=1.17.1=py312h9205ec4_1
- charset-normalizer=3.3.2=pyhd3eb1b0_0
- click=8.1.8=py312hecd8cb5_0
- conda=25.3.1=py312hecd8cb5_0
- conda-anaconda-telemetry=0.1.2=py312hecd8cb5_0
- conda-anaconda-tos=0.1.2=py312hecd8cb5_0
- conda-content-trust=0.2.0=py312hecd8cb5_1
- conda-libmamba-solver=25.1.1=pyhd3eb1b0_0
- conda-package-handling=2.4.0=py312hecd8cb5_0
- conda-package-streaming=0.11.0=py312hecd8cb5_0
- contourpy=1.3.1=py312h1962661_0
- cpp-expected=1.1.0=h1962661_0
- cryptography=43.0.3=py312he15b966_1
- cycler=0.11.0=pyhd3eb1b0_0
- distro=1.9.0=py312hecd8cb5_0
- django=5.1.3=py312hecd8cb5_0
- djhtml=3.0.7=pyhd8ed1ab_0
- expat=2.6.4=h6d0c2b6_0
- fmt=9.1.0=ha357a0b_1
- fonttools=4.55.3=py312h46256e1_0
- freetype=2.13.3=h02243ff_0
- frozendict=2.4.2=py312hecd8cb5_0
- icu=73.1=hcec6c5f_0
- idna=3.7=py312hecd8cb5_0
- jpeg=9e=h46256e1_3
- jsonpatch=1.33=py312hecd8cb5_1
- jsonpointer=2.1=pyhd3eb1b0_0
- kiwisolver=1.4.8=py312h6d0c2b6_0
- krb5=1.20.1=h428f121_1
- lcms2=2.16=h4f63f0c_0
- lerc=4.0.0=h6d0c2b6_0
- libarchive=3.7.7=h4c66a04_0
- libcurl=8.11.1=h9bcc28a_0
- libcxx=14.0.6=h9765a3e_0
- libdeflate=1.22=h46256e1_0
- libedit=3.1.20230828=h6c40b1e_0
- libev=4.33=h9ed2024_1
- libffi=3.4.4=hecd8cb5_1
- libgfortran=5.0.0=11_3_0_hecd8cb5_28
- libgfortran5=11.3.0=h9dfd629_28
- libiconv=1.16=h6c40b1e_3
- libmamba=2.0.5=hfd235c6_1
- libmambapy=2.0.5=py312h1962661_1
- libnghttp2=1.57.0=h9beae6a_0
- libopenblas=0.3.29=h3f8574a_0
- libpng=1.6.39=h6c40b1e_0
- libsolv=0.7.30=h2761308_1
- libssh2=1.11.1=h3a17b82_0
- libtiff=4.5.1=h6fa9cd1_1
- libwebp-base=1.3.2=h46256e1_1
- libxml2=2.13.5=h6070cd6_0
- llvm-openmp=14.0.6=h0dcd299_0
- lz4-c=1.9.4=hcec6c5f_1
- markdown=3.8=py312hecd8cb5_0
- markdown-it-py=2.2.0=py312hecd8cb5_1
- matplotlib=3.10.0=py312hecd8cb5_0
- matplotlib-base=3.10.0=py312h919b35b_0
- mdurl=0.1.0=py312hecd8cb5_0
- menuinst=2.2.0=py312hecd8cb5_1
- mypy_extensions=1.0.0=py312hecd8cb5_0
- ncurses=6.4=hcec6c5f_0
- nlohmann_json=3.11.2=hcec6c5f_0
- numexpr=2.10.1=py312hc59c7be_0
- numpy=2.0.1=py312h255ab90_1
- numpy-base=2.0.1=py312h12d8432_1
- openjpeg=2.5.2=hbf2204d_0
- openssl=3.5.0=hc426f3f_1
- packaging=24.2=py312hecd8cb5_0
- pandas=2.2.3=py312h6d0c2b6_0
- pathspec=0.10.3=py312hecd8cb5_0
- pcre2=10.42=h9b97e30_1
- pillow=11.1.0=py312h47bf62f_0
- pip=25.0=py312hecd8cb5_0
- platformdirs=3.10.0=py312hecd8cb5_0
- pluggy=1.5.0=py312hecd8cb5_0
- pybind11-abi=5=hd3eb1b0_0
- pycosat=0.6.6=py312h46256e1_2
- pycparser=2.21=pyhd3eb1b0_0
- pydantic=2.10.3=py312hecd8cb5_0
- pydantic-core=2.27.1=py312h83de92b_0
- pygments=2.19.1=py312hecd8cb5_0
- pymysql=1.1.1=pyhd8ed1ab_1
- pyparsing=3.2.0=py312hecd8cb5_0
- pypinyin=0.54.0=pyhd8ed1ab_0
- pysocks=1.7.1=py312hecd8cb5_0
- python=3.12.9=hcd54a6c_0
- python-dateutil=2.9.0post0=py312hecd8cb5_2
- python-tzdata=2025.2=pyhd3eb1b0_0
- python.app=3=py312h46256e1_1
- pytz=2024.1=py312hecd8cb5_0
- pyyaml=6.0.2=py312h46256e1_0
- readline=8.2=hca72f7f_0
- reproc=14.2.4=hcec6c5f_2
- reproc-cpp=14.2.4=hcec6c5f_2
- requests=2.32.3=py312hecd8cb5_1
- rich=13.9.4=py312hecd8cb5_0
- ruamel.yaml=0.18.6=py312h46256e1_0
- ruamel.yaml.clib=0.2.8=py312h46256e1_0
- setuptools=75.8.0=py312hecd8cb5_0
- simdjson=3.10.1=h1962661_0
- six=1.17.0=py312hecd8cb5_0
- spdlog=1.11.0=ha357a0b_0
- sqlite=3.45.3=h6c40b1e_0
- sqlparse=0.5.3=pyhd8ed1ab_0
- tk=8.6.14=h4d00af3_0
- tornado=6.4.2=py312h46256e1_0
- tqdm=4.67.1=py312h8e4b320_0
- truststore=0.10.0=py312hecd8cb5_0
- typing-extensions=4.12.2=py312hecd8cb5_0
- typing_extensions=4.12.2=py312hecd8cb5_0
- tzdata=2025a=h04d1e81_0
- unicodedata2=15.1.0=py312h46256e1_1
- urllib3=2.3.0=py312hecd8cb5_0
- wheel=0.45.1=py312hecd8cb5_0
- xz=5.4.6=h6c40b1e_1
- yaml=0.2.5=haf1e3a3_0
- yaml-cpp=0.8.0=hcec6c5f_1
- zlib=1.2.13=h4b97444_1
- zstandard=0.23.0=py312h5bcdf72_1
- zstd=1.5.6=h138b38a_0
prefix: /opt/miniconda3
里面的内容非常多。这是因为我没有配置虚拟环境,命令会把我所有的包都下载下来。有很多的包是我在上一个项目用到但是在这个项目中没有用到的,比如numpy
和matplotlib
。
因此,我们需要创建虚拟环境,做好项目隔离。
创建虚拟环境的好处
项目依赖隔离
- 不同的 Python 项目可能需要不同版本的库(如
numpy
、django
等),甚至不同版本的 Python 解释器。 - 虚拟环境允许每个项目拥有独立的依赖库,避免全局安装(
pip install
)导致的版本冲突问题。
便于依赖管理
虚拟环境可以配合
requirements.txt
或pipenv
/poetry
等工具记录项目依赖,方便团队协作或部署。pip freeze > requirements.txt # 导出依赖 pip install -r requirements.txt # 重新安装依赖
支持多 Python 版本
如果机器上安装了多个 Python 版本(如 Python 3.7 和 3.10),可以为每个项目指定不同的 Python 解释器:
python3.7 -m venv myenv # 使用 Python 3.7 创建虚拟环境
简化部署与移植
- 虚拟环境的所有依赖都集中在项目目录中(如
venv/
文件夹),便于打包或复制到其他环境运行。
如何创建本地虚拟环境
三种方式创建虚拟环境
方法 | 常用命令 | 底层机制 | 是否依赖 Conda | 适用场景 |
---|---|---|---|---|
python |
python -m venv myenv |
标准库 venv 模块 |
❌ | 轻量项目、纯 Python 环境 |
pip |
pip install virtualenv + virtualenv myenv |
virtualenv 第三方包 |
❌ | 对旧版本 Python 或多版本管理更灵活 |
conda |
conda create -n myenv python=3.10 |
Conda 虚拟环境系统 | ✅ | 科研、需要科学库或跨平台兼容 |
- 注意:这里的
pip
实际上是不能创建虚拟环境的,是要通过virtualenv
第三方包
使用建议总结:
场景 | 推荐方式 |
---|---|
Web 后端、轻量开发 | python -m venv |
多版本 Python 项目 | virtualenv |
数据分析 / AI / 科研项目 | conda create |
为什么不推荐使用 Conda 来做 Web 项目虚拟环境?
问题 | 原因 |
---|---|
🔧 环境过重 | Conda 虚拟环境大(几百 MB 起),打包部署不方便 |
🚫 PyPI 兼容性问题 | Conda 安装包并不总是最新,有些库(如某些 Django 扩展)只能用 pip 安装 |
🐳 Docker 部署复杂 | Conda Docker 镜像比 venv 的镜像大很多,CI/CD 会慢 |
🚀 Web 项目不依赖 Conda 的强项 | 你不需要 NumPy、Pandas、SciPy 这类科学计算库 |
如何创建虚拟环境(Django项目)
查看自己的python用的是哪个版本:
(base) xxxx@xxxxdeMacBook-Pro LinNote % which python3 /usr/bin/python3 (base) xxxx@xxxxdeMacBook-Pro LinNote % which python python: aliased to /opt/miniconda3/bin/python3
创建项目根目录
mkdir LinNote cd LinNote
创建虚拟环境
python -m venv .venv
部分 含义 python
表示用 Python 3 的解释器执行命令 -m venv
表示运行 Python 内置模块 venv
,这是用来创建虚拟环境的模块.venv
(最后这个)是你要创建的虚拟环境的目录名,你可以自己起名,比如 env
、venv
、myenv
激活虚拟环境
source .venv/bin/activate # Linux/macOS .venv\Scripts\activate # Windows
安装依赖
pip install django
使用Django创建项目: 在当前目录创建项目
django-admin startproject LinNote .
导出依赖
pip freeze > requirements.txt
requirements.txt
的内容如下:asgiref==3.8.1 Django==5.2.1 sqlparse==0.5.3
最后的目录结构:
LinNote/ ├── .venv/ ├── LinNote/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── manage.py ├── requirements.txt
但是,如果我们运行的是
django-admin startproject LinNote
,那么最终的目录会是这样的:LinNote/ ← 顶级文件夹(项目外层) ├── .venv/ ← ❌ 虚拟环境和manage.py不是在同一层 ├── LinNote/ ← 实际项目目录 │ ├── blog/ │ ├── LinNote/ │ ├── manage.py │ └── requirements.txt ← 放在顶级目录
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com