本篇所有操作均在基于 Ubuntu 16.04 LTS 的虚拟机下完成,且使用 Vagrant 来操作虚拟机系统,虚拟机系统 VirtualBox Version: 7.0
一、包管理
Python 的第三方包很强大,使得我们不需要额外造轮子就可以享用,轮子直达:https://zhuanlan.zhihu.com/p/511280808。
1、第三方包的主要分布
(1)PYPI
Python 的官方仓库,https://pypi.python.org/pypi
(2)Github
Github 上有很多 Python 工具包,例如:解析、格式化、存储、验证手机号码 https://github.com/daviddrysdale/python-phonenumbers
(3)Bitbucket
跟 Github 一样,用于代码托管,官方网址:https://bitbucket.org
2、安装和管理第三方包
(1)Python 社区开发的工具
pip、easy_install 等
(2)系统自带的包管理器
yum、emerge、apt-get 等
(3)源码安装
通过命令行 $ python setup.py install
进行安装
3、pip 使用介绍
目前安装、管理第三方包的主流工具是 pip 且其已经被内置到 python2.7.9 和 python3.4 及以上版本里面了,主要原因:
(1)支持第三方包的安装、卸载、升级等等包管理功能
(2)支持二进制包使用 wheel 格式(后缀是 .whl)
(3)支持虚拟环境工具 virtualenv
(4)可以集中管理项目依赖列表文件 requirements.txt
坑:pypi.python.org 在国内被墙了导致装包时速度过慢或者无法安装(请求超时)等问题,更换为豆瓣源可以解决
1
2
3
4
5
6
7
8
9
10
11
12
13
~ ubuntu@WEB
(venv) ❯ pip install xlwt
Collecting xlwt
Could not fetch URL https://pypi.python.org/simple/xlwt/: There was a problem confirming the ssl certificate: EOF occurred in violation of protocol (_ssl.c:590) - skipping
Could not find a version that satisfies the requirement xlwt (from versions: )
No matching distribution found for xlwt
~ ubuntu@WEB 6s
(venv) ❯ pip install xlwt -i https://pypi.douban.com/simple
Collecting xlwt
Using cached https://pypi.doubanio.com/packages/44/48/def306413b25c3d01753603b1a222a011b8621aed27cd7f89cbc27e6b0f4/xlwt-1.3.0-py2.py3-none-any.whl
Installing collected packages: xlwt
Successfully installed xlwt-1.3.0
4、构建和分发项目的工具
如果想要把自己的项目分享出去,放到 PYPI 或者其他托管服务上时,需要使用构建和分发项目工具来实现。除非项目的环境依赖简单到只需要用到 distutils ,否则推荐使用 setuptools 包。
二、虚拟环境
虚拟环境可以解决以下问题:
(1)系统自带的 Python 是 2.6,而新项目要用到 Python 2.7 中的某些特性
(2)不同的项目之间使用了不同版本的某些包,但由于某些原因(如有依赖冲突)而无法直接升级到最新版本
(3)所有的包若都共用一个目录,很容易出现更新了项目A的依赖,却影响了项目B用到的依赖的情况
使用虚拟环境可以让全局的 site-package 目录非常干净,从而实现对环境进行隔离。目前主流的创建和管理虚拟环境的工具有 virtualenv 和 pyvenv。
1、安装和使用 virtualenv
(1)安装 virtualenv
1
> pip install virtualenv
(2)使用 virtualenv 创建一个 Python 环境,环境名为 venv
1
2
3
4
5
6
❯ virtualenv venv
New python executable in /home/ubuntu/venv/bin/python
Installing setuptools, pip, wheel...done.
~ ubuntu@WEB 10s
❯
(3)激活虚拟环境 venv
激活成功后,可以看到已经不再使用系统环境变量中的 Python 了,而是在虚拟环境 /home/ubuntu/venv 下创建了一个单独的 python 环境。原系统环境变量的 Python 是 /usr/bin/python。
1
2
3
4
5
6
7
8
❯ source venv/bin/activate
~ ubuntu@WEB
(venv) ❯
(venv) ❯ which python
/home/ubuntu/venv/bin/python
(4)退出虚拟环境 venv
1
2
3
4
5
~ ubuntu@WEB
(venv) ❯ deactivate
~ ubuntu@WEB
❯
2、virtualenv 定制化
效果实现:在生成虚拟环境 venv 的同时安装 flake8 的自定义脚本
(1)更改 virtualenv 权限
让 ubuntu 这个用户对 virtualenv 文件可见,方便直接替换
1
2
3
4
5
6
7
8
9
~ ubuntu@WEB
❯ which virtualenv
/usr/local/bin/virtualenv
~ ubuntu@WEB
❯ sudo chown ubuntu:ubuntu /usr/local/bin/virtualenv
~ ubuntu@WEB
❯
如果不改变文件的权限而直接进行定制化脚本的替换,则抛出以下异常:
1
2
3
4
5
6
7
8
❯ python web_develop/chapter2/section2/create-venv-script.py
Updating /usr/local/bin/virtualenv
Traceback (most recent call last):
File "web_develop/chapter2/section2/create-venv-script.py", line 22, in <module>
main()
File "web_develop/chapter2/section2/create-venv-script.py", line 17, in main
with open(virtualenv_path, 'w') as f:
IOError: [Errno 13] Permission denied: '/usr/local/bin/virtualenv'
(2)编写定制化的脚本
原版本的 virtualenv 内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ which virtualenv
/usr/local/bin/virtualenv
~ ubuntu@WEB
❯ cat /usr/local/bin/virtualenv
#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from virtualenv import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
定制化的脚本可以全局替换到原版本,实现在默认的虚拟环境安装完成后去执行其他的工作,脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# coding=utf-8
import subprocess
import virtualenv
virtualenv_path = subprocess.check_output(['which', 'virtualenv']).strip()
EXTRA_TEXT = '''
def after_install(options, home_dir):
subprocess.call(['{}/bin/pip'.format(home_dir), 'install', 'flake8'])
'''
def main():
text = virtualenv.create_bootstrap_script(EXTRA_TEXT, python_version='2.7')
print 'Updating %s' % virtualenv_path
with open(virtualenv_path, 'w') as f:
f.write(text)
if __name__ == '__main__':
main()
(3)执行并替换原有版本
执行定制化脚本,替换原有的版本 /usr/local/bin/virtualenv
1
2
3
4
5
6
~ ubuntu@WEB
❯ python web_develop/chapter2/section2/create-venv-script.py
Updating /usr/local/bin/virtualenv
~ ubuntu@WEB
❯
(4)重新生成虚拟环境
生成虚拟环境 tmp 并检查有无自动安装 flake8 等各种包
1
2
3
4
5
❯ virtualenv venv
New python executable in /home/ubuntu/venv/bin/python2.7
Also creating executable in /home/ubuntu/venv/bin/python
Installing setuptools, pip, wheel...done.
Collecting flake8
坑:在玩的过程中倘若出现了怎么都无法解决的异常,最好的办法就是出厂化处理
① 关闭虚拟机 > vagrant halt
② 进入 VirtualBox 中删除该虚拟机的所有文件
③ 重新启动虚拟机 > vagrant up
④ 重新进行初始化 > vagrant provision
⑤ 重新连接虚拟机 > vagrant ssh
,登录成功后再重新进行操作
3、virtualenvwrapper
virtualenvwrapper 是对 virtualenv 的功能扩展,主要有以下用途:
- 管理全部虚拟环境,方便创建、删除和拷贝虚拟环境
- 单个命令就可以切换不同的虚拟环境
- 使用 Tab 补全虚拟环境
- 用户粒度的钩子支持
(1)安装豆瓣源
1
2
~ ubuntu@WEB
❯ pip install virtualenvwrapper -i https://pypi.douban.com/simple
(2)初始化添加钩子模板
初始化 virtualenvwrapper 之后 ~/venv 目录也会添加一些用户级别的 virtualenvwrapper 的钩子模板。
1
2
3
4
5
6
7
❯ export WORKON_HOME=~/venv
~ ubuntu@WEB
❯ source /usr/local/bin/virtualenvwrapper.sh
~ ubuntu@WEB
❯
通常上述两行会放在 shell 的配置文件里面,这样每次登录时就自动初始化了。打开 ~/.zshrc 文件,在文件末尾添加上述两行,保存。
1
❯ vim ~/.zshrc
(3)创建虚拟环境
使用 mkvirtualenv
来创建虚拟环境,同时还会添加以下5个项目级别的钩子模板。
- predeactivate:在虚拟环境取消激活之前执行
- postdeactivate:在虚拟环境取消激活之后执行
- preactivate:在虚拟环境激活之前执行
- postactivate:在虚拟环境激活之后执行
- get_env_details:使用 lsvirtualenv/showvirtualenv 等命令时,对于当前环境的额外钩子,可以添加虚拟环境介绍等内容
1
2
3
4
5
6
7
8
9
10
11
❯ mkvirtualenv venv1
New python executable in /home/ubuntu/venv/venv1/bin/python
Installing setuptools, pip, wheel...done.
virtualenvwrapper.user_scripts creating /home/ubuntu/venv/venv1/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/ubuntu/venv/venv1/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/ubuntu/venv/venv1/bin/preactivate
virtualenvwrapper.user_scripts creating /home/ubuntu/venv/venv1/bin/postactivate
virtualenvwrapper.user_scripts creating /home/ubuntu/venv/venv1/bin/get_env_details
~ ubuntu@WEB 14s
(venv1) ❯
(4)workon 切换虚拟环境
使用 workon + Tab 键实现虚拟环境的切换
1
2
3
4
5
6
❯ workon <Tab>
local venv1 venv3 venv4
❯ workon venv3
~ ubuntu@WEB
(venv3) ❯
(5)常用命令
- lsvirtualenv:列出全部的虚拟环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
❯ lsvirtualenv local ===== venv1 ===== venv3 ===== venv4 ===== ~ ubuntu@WEB ❯
- showvirtualenv:列出单个虚拟环境的信息
1
❯ showvirtualenv [环境名]
- rmvirtualenv:删除一个虚拟环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
❯ rmvirtualenv venv3 Removing venv3... ~ ubuntu@WEB ❯ lsvirtualenv local ===== venv1 ===== venv4 =====
- cpvirtualenv:拷贝虚拟环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
❯ cpvirtualenv venv4 venv3 Copying venv4 as venv3... ~ ubuntu@WEB (venv3) ❯ deactivate ~ ubuntu@WEB ❯ lsvirtualenv local ===== venv1 ===== venv3 ===== venv4 =====
- allvirtualenv:对当前所有虚拟环境执行统一的命令。比如给所有虚拟环境都安装 xlwt,就可以用以下命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
❯ allvirtualenv pip install xlwt -i https://pypi.douban.com/simple local ===== Requirement already satisfied (use --upgrade to upgrade): xlwt in ./lib/python2.7/site-packages venv1 ===== Collecting xlwt Using cached https://pypi.doubanio.com/packages/44/48/def306413b25c3d01753603b1a222a011b8621aed27cd7f89cbc27e6b0f4/xlwt-1.3.0-py2.py3-none-any.whl Installing collected packages: xlwt Successfully installed xlwt-1.3.0 venv3 ===== Collecting xlwt Using cached https://pypi.doubanio.com/packages/44/48/def306413b25c3d01753603b1a222a011b8621aed27cd7f89cbc27e6b0f4/xlwt-1.3.0-py2.py3-none-any.whl Installing collected packages: xlwt Successfully installed xlwt-1.3.0 venv4 ===== Collecting xlwt Using cached https://pypi.doubanio.com/packages/44/48/def306413b25c3d01753603b1a222a011b8621aed27cd7f89cbc27e6b0f4/xlwt-1.3.0-py2.py3-none-any.whl Installing collected packages: xlwt Successfully installed xlwt-1.3.0
- cdvirtualenv:直接切换到虚拟环境的子目录里
1 2 3 4 5 6 7 8 9 10 11
❯ workon venv3 ~ ubuntu@WEB (venv3) ❯ cdvirtualenv bin ~/venv/venv3/bin ubuntu@WEB (venv3) ❯ pwd /home/ubuntu/venv/venv3/bin ~/venv/venv3/bin ubuntu@WEB (venv3) ❯
(5)用户级别的钩子脚本
钩子(hook)脚本是被一些版本库事件触发的程序,例如创建新版本,或修改非版本控制的属性。每种钩子都会被告知事件的足够信息,操作的目标,触发事件的用户名。依赖于钩子的输出或返回状态,钩子程序可以继续执行,停止或以某种方式挂起。
1
2
3
4
~/venv/venv3/bin ubuntu@WEB
(venv3) ❯ cat /home/ubuntu/venv/venv3/bin/postdeactivate
#!/usr/bin/zsh
# This hook is sourced after this virtualenv is deactivated.