所有的 Python 開發者都清楚,Python 之是以如此受歡迎,能夠在衆多進階語言中,脫穎而出,除了文法簡單,上手容易之外,更多還要歸功于 Python 生态的完備,有數以萬計的 Python 愛好者願意以 Python 為基礎封裝出各種有利于開發的第三方工具包。
這才使用我們能夠以最快的速度開發出一個滿足基本需要的項目,而不是每次都重複造輪子。
Python 從1991年誕生到現在,已經過去28個年頭了,這其間産生了數以萬計的第三方包,且每個包都會不斷更新,會有越來越多的版本。
當你在一個複雜的項目環境中,如果沒有一個有效的依賴包管理方案,項目的維護将會是一個大問題。
pip 是官方推薦的包管理工具,在大多數開發者眼裡,pip 幾乎是 Python 的标配。
當然也有其他的包管理工具
- distutils:僅用于打包和安裝,嚴格來講不算是包管理工具
- setuptools:distutils的增強版,擴充了distutils,提供更多的功能,引入包依賴的管理,easy_install就是它的一個指令行工具,引入了 egg 的檔案格式。
- Pipenv:一個集依賴包管理(pip)及虛拟環境管理(virtualenv)的工具
- 還有其他的,這裡不一一列出。
今天的主角是 pip ,大家肯定不會陌生。但我相信不少人,隻是熟悉幾個常用的用法,而對于其他幾個低頻且實用的用法,卻知之甚少,這兩天,我查閱官方文檔,把這些用法整理了一下,應該是網絡上比較全的介紹。
1. 查詢軟體包
查詢目前環境安裝的所有軟體包
$ pip list
查詢 pypi 上含有某名字的包
$ pip search pkg
查詢目前環境中可更新的包
$ pip list --outdated
查詢一個包的詳細内容
$ pip show pkg
2. 下載下傳軟體包
在不安裝軟體包的情況下下載下傳軟體包到本地
$ pip download --destination-directory /local/wheels -r requirements.txt
下載下傳完,總歸是要安裝的,可以指定這個目錄中安裝軟體包,而不從 pypi 上安裝。
$ pip install --no-index --find-links=/local/wheels -r requirements.txt
當然你也從你下載下傳的包中,自己建構生成 wheel 檔案
$ pip install wheel
$ pip wheel --wheel-dir=/local/wheels -r requirements.txt
3. 安裝軟體包
使用
pip install <pkg>
可以很友善地從 pypi 上搜尋下載下傳并安裝 python 包。
如下所示
$ pip install requests
這是安裝包的基本格式,我們也可以為其添加更多參數來實作不同的效果。
3.1 隻從本地安裝,而不從 pypi 安裝
# 前提你得保證你已經下載下傳 pkg 包到 /local/wheels 目錄下
$ pip install --no-index --find-links=/local/wheels pkg
3.2 限定版本進行軟體包安裝
以下三種,對單個 python 包的版本進行了限制
# 所安裝的包的版本為 2.1.2
$ pip install pkg==2.1.2
# 所安裝的包必須大于等于 2.1.2
$ pip install pkg>=2.1.2
# 所安裝的包必須小于等于 2.1.2
$ pip install pkg<=2.1.2
以下指令用于管理/控制整個 python 環境的包版本
# 導出依賴包清單
pip freeze >requirements.txt
# 從依賴包清單中安裝
pip install -r requirements.txt
# 確定目前環境軟體包的版本(并不確定安裝)
pip install -c constraints.txt
3.3 限制不使用二進制包安裝
由于預設情況下,wheel 包的平台是運作 pip download 指令 的平台,是以可能出現平台不适配的情況。
比如在 MacOS 系統下得到的 pymongo-2.8-cp27-none-macosx_10_10_intel.whl 就不能在 linux_x86_64 安裝。
使用下面這條指令下載下傳的是 tar.gz 的包,可以直接使用 pip install 安裝。
比 wheel 包,這種包在安裝時會進行編譯,是以花費的時間會長一些。
# 下載下傳非二進制的包
$ pip download --no-binary=:all: pkg
# 安裝非二進制的包
$ pip install pkg --no-binary
3.4 指定代理伺服器安裝
當你身處在一個内網環境中時,無法直接連接配接公網。這時候你使用
pip install
安裝包,就會失敗。
面對這種情況,可以有兩種方法:
- 下載下傳離線包拷貝到内網機器中安裝
- 使用代理伺服器轉發請求
第一種方法,雖說可行,但有相當多的弊端
- 步驟繁雜,耗時耗力
- 無法處理包的依賴問題
這裡重點來介紹,第二種方法:
$ pip install --proxy [user:passwd@]http_server_ip:port pkg
每次安裝包就發輸入長長的參數,未免有些麻煩,為此你可以将其寫入配置檔案中:
$HOME/.config/pip/pip.conf
對于這個路徑,說明幾點
- 不同的作業系統,路徑各不相同
# Linux/Unix:
/etc/pip.conf
~/.pip/pip.conf
~/.config/pip/pip.conf
# Mac OSX:
~/Library/Application Support/pip/pip.conf
~/.pip/pip.conf
/Library/Application Support/pip/pip.conf
# Windows:
%APPDATA%pippip.ini
%HOME%pippip.ini
C:Documents and SettingsAll UsersApplication DataPyPApippip.conf (Windows XP)
C:ProgramDataPyPApippip.conf (Windows 7及以後)
- 若在你的機子上沒有此檔案,則自行建立即可
如何配置,這邊給個樣例:
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
# 替換出自己的代理位址,格式為[user:passwd@]proxy.server:port
proxy=http://xxx.xxx.xxx.xxx:8080
[install]
# 信任阿裡雲的鏡像源,否則會有警告
trusted-host=mirrors.aliyun.com
3.5 安裝使用者私有軟體包
很多人可能還不清楚,python 的安裝包是可以使用者隔離的。
如果你擁有管理者權限,你可以将包安裝在全局環境中。在全局環境中的這個包可被該機器上的所有擁有管理者權限的使用者使用。
如果一台機器上的使用者不隻一樣,自私地将在全局環境中安裝或者更新某個包,是不負責任且危險的做法。
面對這種情況,我們就想能否安裝單獨為我所用的包呢?
慶幸的是,還真有。
我能想到的有兩種方法:
- 使用虛拟環境
- 将包安裝在使用者的環境中
虛拟環境,之前寫過幾篇文章,這裡不再展開講。
今天的重點是第二種方法,教你如何安裝使用者私有的包?
指令也很簡單,隻要加上
--user
參數,pip 就會将其安裝在目前使用者的
~/.local/lib/python3.x/site-packages
下,而其他使用者的 python 則不會受影響。
pip install --user pkg
來舉個例子
# 在全局環境中未安裝 requests
[root@localhost ~]# pip list | grep requests
[root@localhost ~]# su - wangbm
[root@localhost ~]#
# 由于使用者環境繼承自全局環境,這裡也未安裝
[wangbm@localhost ~]# pip list | grep requests
[wangbm@localhost ~]# pip install --user requests
[wangbm@localhost ~]# pip list | grep requests
requests (2.22.0)
[wangbm@localhost ~]#
# 從 Location 屬性可發現 requests 隻安裝在目前使用者環境中
[wangbm@ws_compute01 ~]$ pip show requests
---
Metadata-Version: 2.1
Name: requests
Version: 2.22.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: [email protected]
Installer: pip
License: Apache 2.0
Location: /home/wangbm/.local/lib/python2.7/site-packages
[wangbm@localhost ~]$ exit
logout
# 退出 wangbm 使用者,在 root 使用者環境中發現 requests 未安裝
[root@localhost ~]$ pip list | grep requests
[root@localhost ~]$
當你身處個人使用者環境中,python 導包時會先檢索目前使用者環境中是否已安裝這個包,已安裝則優先使用,未安裝則使用全局環境中的包。
驗證如下:
>>> import sys
>>> from pprint import pprint
>>> pprint(sys.path)
['',
'/usr/lib64/python27.zip',
'/usr/lib64/python2.7',
'/usr/lib64/python2.7/plat-linux2',
'/usr/lib64/python2.7/lib-tk',
'/usr/lib64/python2.7/lib-old',
'/usr/lib64/python2.7/lib-dynload',
'/home/wangbm/.local/lib/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages',
'/usr/lib64/python2.7/site-packages/gtk-2.0',
'/usr/lib/python2.7/site-packages',
'/usr/lib/python2.7/site-packages/pip-18.1-py2.7.egg',
'/usr/lib/python2.7/site-packages/lockfile-0.12.2-py2.7.egg']
>>>
4. 解除安裝軟體包
就一條指令,不再贅述
$ pip uninstall pkg
5. 更新軟體包
想要對現有的 python 進行更新,其本質上也是先從 pypi 上下載下傳最新版本的包,再對其進行安裝。是以更新也是使用
pip install
,隻不過要加一個參數
--upgrade
。
$ pip install --upgrade pkg
在更新的時候,其實還有一個不怎麼用到的選項
--upgrade-strategy
,它是用來指定更新政策。
它的可選項隻有兩個:
-
:更新全部依賴包eager
-
:隻有當舊版本不能适配新的父依賴包時,才會更新。only-if-need
在 pip 10.0 版本之後,這個選項的預設值是
only-if-need
,是以如下兩種寫法是一互緻的。
pip install --upgrade pkg1
pip install --upgrade pkg1 --upgrade-strategy only-if-need
以上幾乎包含了 pip 的所有常用使用場景,為了友善,我将其整理成一張表格,如果你需要,可以關注我的公衆号(Python程式設計時光),背景回複“pip”,可擷取高清無水印圖檔。