我有一个现有的虚拟环境,里面有很多包,但是是旧版本的Django。
我想做的是复制这个环境,这样我就有了另一个环境,里面有完全相同的包,但是是一个新版本的Django。我该怎么做呢?
最简单的方法是使用pip生成需求文件。需求文件基本上是一个包含所有你想要安装的python包的列表(或者在pip生成文件的情况下已经安装),以及它们的版本。
要生成需求文件,进入您的原始虚拟环境,并运行:
pip freeze > requirements.txt
这将为您生成requirements.txt文件。如果在您喜欢的文本编辑器中打开该文件,您将看到如下内容:
Django==1.3
Fabric==1.0.1
etc...
现在,将表示Django==x.x
的行编辑为Django==1.3
(或您想在新virtualenv中安装的任何版本)。
pip install -r requirements.txt
并且pip将自动下载并安装在requirements.txt文件中列出的所有python模块,无论您指定的是哪个版本!
另一个选择是使用virtualenv-clone
包:
克隆不可重定位虚拟环境的脚本。
virtualenvwrapper
提供复制virtualenv的命令
cpvirtualenv ENVNAME [TARGETENVNAME]
最简单的选择是使用virtualenv-clone
包。
复制venv1
到venv2
,遵循以下步骤:
-
在
venv1
或虚拟环境venv_dummy
中安装virtualenv-clone
。创建venv_dummy
:python -m virtualenv venv_dummy source venv_dummy/bin/activate
-
安装
virtualenv-clone
:(venv_dummy): pip install virtualenv-clone
-
复制
venv1
到venv2
:(venv_dummy): virtualenv-clone venv1/ venv2/
如果您正在使用Anaconda,您可以直接运行:
conda create --name myclone --clone myenv
将myenv
复制到新创建的环境myclone
。
这是我克隆python虚拟环境的命令。
packs=`source-path/bin/pip freeze` && python3 -m venv <env-name> && target-path/bin/pip install $packs
以上命令的约定:
- source-path =要克隆的环境的路径,例如
/home/john/envs/oldenv
。 - env-name =克隆的环境名称,例如
myenv
,也可以是路径。/home/john/envs/myenv
- target-path =新克隆环境的路径,例如
/home/john/envs/<env-name>
使用这个的优点或者为什么我更喜欢这个
- 不需要生成requirements.txt文件
- 克隆过程中不激活/去激活任何环境。
- 单个命令执行(一次运行3个命令)。
在某些情况下,您可能希望在克隆环境时排除全局包,您可以将source-path/bin/pip freeze
替换为source-path/bin/pip freeze --local
,这里有更多关于--local
的信息
如果您使用pip "venv"我复制粘贴了包含虚拟环境的文件夹,并手动更改了复制文件夹中的bin文件夹中的文件。我不知道它是否有效,但它有效!
你能不能直接:
- 将现有的虚拟env目录复制到新的目录
- 更新到新的Django?
pip可以工作,但是在没有网络的电脑上是一个问题。
我为此写了一个小代码,它为我工作。我把它写在这里是因为它可能对别人有用。
(注意:我在Windows上测试过)
- 复制项目文件夹
- 粘贴项目文件夹到另一个目录
- 更改此代码中的地址部分,并运行以下代码:
import os
# The new address of our script folder
script_folder = r'D:Python proqramspdf_to_excelvenvScripts'
# the old address of our venv folder
old_path = rb'C:UsersAVG-dellDesktoppdf_to_excelvenv'
# the new address of our venv folder
new_path = rb"D:Python proqramspdf_to_excelvenv"
def find_replace( folder ):
names = os.listdir( folder )
for name in names:
current_path = os.path.join( folder, name )
if os.path.isdir( current_path ):
find_replace( current_path )
elif os.path.isfile( current_path ) :
try:
with open( current_path ,'rb' ) as f:
data = f.read()
if old_path in data:
print( current_path )
data2 = data.replace( old_path , new_path )
with open( current_path , 'wb' ) as f:
f.write(data2)
except:
pass
find_replace( script_folder )
print('completed')