Python代码编写及运行时,往往依赖若干的包。
在计算机重装后及在不同计算机上做同样的事,如果依赖的包比较多,一个一个手动安装是比较烦琐而无聊的事情。
为减少这种情况下的工作量,编写了一个Python3脚本。
该脚本可以:
1.利用 pip3 list 命令列举目标计算机上已经存在的Python3包,并保存为目标包列表文件,供另一个计算机配置使用。
2.利用目标包列表文件,利用 pip3 install 命令安装相应的包。为避免重复安装已经存在的包,在执行过程中,会先列举本机已安装的包,并将目标包列表剔除本机已经安装的包,只安装增量包。
注意:部分包可能因为如下的原因不能成功安装:(1)PyPi库中不存在(2)PyPi库中缺少依赖项(3)其它导致失败的原因。
本脚本在执行完操作2后,会再次列举本机已经安装的包,求出并打印目标包增量,提示用户手动安装上述安装失败的包,同时将该信息保存为文件备检(FailedPackages.list)。
使用时,将下面的脚本复制为.py为扩展名的文件(并根据需要视情设置可执行属性),运行。
向某计算机迁移时,需要复制本脚本和本脚本在目标计算机上运行1所产生的的目标包列表文件(dest_packages.list)。
import os
escapes = ['Package', 'pip', 'pip3', '#', '_', '-']
def get_packages_installed(file_name):
'''
Get installed python3 packages.
'''
os.system('pip3 list > ' + file_name)
return
def has_escape(s, escapes):
s = s.strip()
if len(s) == 0:
return True
for e in escapes:
if len(e) == 1:
if s[0] == e:
return True
else:
if s == e:
return True
return False
def extract_package_name(file_name):
'''
Extract package names from text file generated by
pip3 list
pip list
conda list
'''
names = []
with open(file_name) as f:
for line in f:
line = line.strip()
cells = line.split()
if has_escape(cells[0], escapes):
#print('ESCAPE:', line)
continue
names.append(cells[0])
return names
def generate_pip_command(names):
command = ''
for name in names:
command += 'pip3 install ' + name + '\n'
return command
#---------------------------------------------------------------------
def get_local_packages():
file_name = 'local_installed_packages.txt'
get_packages_installed(file_name)
local_packages = extract_package_name(file_name)
os.system('rm %s'%file_name)
return local_packages
def save_packages(file_name, packages):
with open(file_name, 'wt') as f:
for package in packages:
f.write(package + '\n')
return
def get_dest_packages(file_name):
packages = []
with open(file_name) as f:
for line in f:
line = line.strip()
packages.append(line)
return packages
#----------------------------------------------------------------------
def generate_dest_package_file(file_name):
dest_packages = get_local_packages()
save_packages(file_name, dest_packages)
return
#generate_dest_package_file('dest_packages.list')
def install_dest_packages(file_name):
dest_packages = get_dest_packages(file_name)
local_packages = get_local_packages()
for package in local_packages:
try:
dest_packages.remove(package)
except:
pass
for package in dest_packages:
command = 'pip3 install %s'%package
#print('\n'*2 + '-'*40 + '\n'*2)
os.system(command)
dest_packages = get_dest_packages(file_name)
local_packages = get_local_packages()
for package in local_packages:
try:
dest_packages.remove(package)
except:
pass
if len(dest_packages):
print('\n\nPackages failed to install')
print('-' * 40)
with open('FailedPackages.list', 'wt') as f:
for package in dest_packages:
print(package)
f.write(package + '\n')
print('-' * 40)
print('Install them manually.')
print('\nDetail in "FailedPackages.list".')
else:
print('\nAll packages installed successfully.')
return
#install_dest_packages('dest_packages.list')
#-------------------------------------------------------------
if __name__ == '__main__':
print('''
Python3 Package Duplicator
---------------------------------
1 Generate Package List
2 Install Packages in List
---------------------------------
your choice ([1]/2) : ''', end='')
ans = input()
if ans == '2':
install_dest_packages('dest_packages.list')
else:
generate_dest_package_file('dest_packages.list')
print('Press "Enter" to exit...')