Python 打包分發工具 setuptools 簡介
點擊上方「
Python開發
」,選擇「置頂公眾號」
關鍵時刻,第一時間送達!
作為Python標準的打包及分發工具,setuptools可以說相當地簡單易用。它會隨著Python一起安裝在你的機器上。你只需寫一個簡短的setup.py安裝文件,就可以將你的Python應用打包。本文就會介紹下如何編寫安裝文件及如何打包分發。
首先,如果你需要另外安裝setuptools,你可以使用下面的命令:
$
wget
http
:
//peak.telecommunity.com/dist/ez_setup.py
$
sudo python
ez_setup
.
py
第一個安裝文件
接下來讓我們編寫安裝文件,假設我們的項目名為setup-demo,包名為myapp,目錄結構如下:
setup
-
demo
/
├
setup
.
py
# 安裝文件
└
myapp
/
# 源代碼
├
__init__
.
py
...
一個最基本的setup.py文件如下:
#coding:utf8
from
setuptools
import
setup
setup
(
name
=
"MyApp"
,
# 應用名
version
=
"1.0"
,
# 版本號
packages
=
[
"myapp"
]
# 包括在安裝包內的Python包
)
執行安裝文件
有了上面的setup.py文件,我們就可以打各種包,也可以將應用安裝在本地Python環境中。
1. 創建egg包
$ python setup.py bdist_egg
該命令會在當前目錄下的」dist」目錄內創建一個egg文件,名為」MyApp-1.0-py2.7.egg」。文件名格式就是」應用名-版本號-Python版本.egg」,我本地Python版本是2.7。同時你會注意到,當前目錄多了」build」和」MyApp.egg-info」子目錄來存放打包的中間結果。
2. 創建tar.gz包
$ python setup.py sdist --formats=gztar
同上例類似,只不過創建的文件類型是tar.gz,文件名為」MyApp-1.0.tar.gz」。
3. 安裝應用
$ python setup.py install
該命令會將當前的Python應用安裝到當前Python環境的」site-packages」目錄下,這樣其他程序就可以像導入標準庫一樣導入該應用的代碼了。
4. 開發方式安裝
$ python setup.py develop
如果應用在開發過程中會頻繁變更,每次安裝還需要先將原來的版本卸掉,很麻煩。使用」develop」開發方式安裝的話,應用代碼不會真的被拷貝到本地Python環境的」site-packages」目錄下,而是在」site-packages」目錄里創建一個指向當前應用位置的鏈接。這樣如果當前位置的源碼被改動,就會馬上反映到」site-packages」里。
引入非Python文件
上例中,我們只會將」myapp」包下的源碼打包,如果我們還想將其他非Python文件也打包,比如靜態文件(JS,CSS,圖片),應該怎麼做呢?這時我們要在項目目錄下添加一個」MANIFEST.in」文件夾。假設我們把所有靜態文件都放在」static」子目錄下,現在的項目結構如下:
setup
-
demo
/
├
setup
.
py
# 安裝文件
├
MANIFEST
.
in
# 清單文件
└
myapp
/
# 源代碼
├
static
/
# 靜態文件目錄
├
__init__
.
py
...
我們在清單文件」MANIFEST.in」中,列出想要在包內引入的目錄路徑:
recursive
-
include
myapp
/
static
*
recursive
-
include
myapp
/
xxx
*
「recursive-include」表明包含子目錄。別急,還有一件事要做,就是在」setup.py」中將」 include_package_data」參數設為True:
#coding:utf8
from
setuptools
import
setup
setup
(
name
=
"MyApp"
,
# 應用名
version
=
"1.0"
,
# 版本號
packages
=
[
"myapp"
],
# 包括在安裝包內的Python包
include_package_data
=
True
# 啟用清單文件MANIFEST.in
)
之後再次打包或者安裝,」myapp/static」目錄下的所有文件都會被包含在內。如果你想排除一部分文件,可以在setup.py中使用」exclude_package_date」參數,比如:
setup
(
...
include_package_data
=
True
,
# 啟用清單文件MANIFEST.in
exclude_package_date
=
{
""
:
[
".gitignore"
]}
)
上面的代碼會將所有」.gitignore」文件排除在包外。如果上述」exclude_package_date」對象屬性不為空,比如」{『myapp』:[『.gitignore』]}」,就表明只排除」myapp」包下的所有」.gitignore」文件。
自動安裝依賴
我們的應用會依賴於第三方的Python包,雖然可以在說明文件中要求用戶提前安裝依賴包,但畢竟很麻煩,用戶還有可能裝錯版本。其實我們可以在setup.py文件中指定依賴包,然後在使用setuptools安裝應用時,依賴包的相應版本就會被自動安裝。讓我們來修改上例中的setup.py文件,加入」install_requires」參數:
#coding:utf8
from
setuptools
import
setup
setup
(
name
=
"MyApp"
,
# 應用名
version
=
"1.0"
,
# 版本號
packages
=
[
"myapp"
],
# 包括在安裝包內的Python包
include_package_data
=
True
,
# 啟用清單文件MANIFEST.in
exclude_package_date
=
{
""
:
[
".gitignore"
]},
install_requires
=
[
# 依賴列表
"Flask>=0.10"
,
"Flask-SQLAlchemy>=1.5,<=2.1"
]
)
上面的代碼中,我們聲明了應用依賴Flask 0.10及以上版本,和Flask-SQLAlchemy 1.5及以上、2.1及以下版本。setuptools會先檢查本地有沒有符合要求的依賴包,如果沒有的話,就會從PyPI中獲得一個符合條件的最新的包安裝到本地。
大家可以執行下試試,你會發現不但Flask 0.10.1(當前最新版本)被自動安裝了,連Flask的依賴包Jinja2和Werkzeug也被自動安裝了,很方便吧。
如果應用依賴的包無法從PyPI中獲取怎麼辦,我們需要指定其下載路徑:
setup
(
...
install_requires
=
[
# 依賴列表
"Flask>=0.10"
,
"Flask-SQLAlchemy>=1.5,<=2.1"
],
dependency_links
=
[
# 依賴包下載路徑
"http://example.com/dependency.tar.gz"
]
)
路徑應指向一個egg包或tar.gz包,也可以是個包含下載地址(一個egg包或tar.gz包)的頁面。個人建議直接指向文件。
自動搜索Python包
之前我們在setup.py中指定了」packages=[『myapp』]」,說明將Python包」myapp」下的源碼打包。如果我們的應用很大,Python包很多怎麼辦。大家看到這個參數是一個列表,我們當然可以將所有的源碼包都列在裡面,但肯定很多人覺得這樣做很傻。的確,setuptools提供了」find_packages()」方法來自動搜索可以引入的Python包:
#coding:utf8
from
setuptools
import
setup
,
find_packages
setup
(
name
=
"MyApp"
,
# 應用名
version
=
"1.0"
,
# 版本號
packages
=
find_packages
(),
# 包括在安裝包內的Python包
include_package_data
=
True
,
# 啟用清單文件MANIFEST.in
exclude_package_date
=
{
""
:
[
".gitignore"
]},
install_requires
=
[
# 依賴列表
"Flask>=0.10"
,
"Flask-SQLAlchemy>=1.5,<=2.1"
]
)
這樣當前項目內所有的Python包都會自動被搜索到並引入到打好的包內。」find_packages()」方法可以限定你要搜索的路徑,比如使用」find_packages(『src』)」就表明只在」src」子目錄下搜索所有的Python包。
補充
zip_safe參數
決定應用是否作為一個zip壓縮後的egg文件安裝在當前Python環境中,還是作為一個以.egg結尾的目錄安裝在當前環境中。因為有些工具不支持zip壓縮文件,而且壓縮後的包也不方便調試,所以建議將其設為False:」zip_safe=False」。
描述信息
部分參數提供了更多當前應用的細節信息,對打包安裝並無任何影響,比如:
setup
(
...
author
=
"Billy He"
,
author_email
=
"billy@bjhee.com"
,
description
=
"This is a sample package"
,
license
=
"MIT"
,
keywords
=
"hello world example"
,
url
=
"http://example.com/HelloWorld/"
,
# 項目主頁
long_description
=
__doc__
,
# 從代碼中獲取文檔注釋
)
更多內容請參閱setuptools的官方文檔。
來源:思誠之道
www.bjhee.com/setuptools.html
Python開發整理髮布,轉載請聯繫作者獲得授權
【點擊成為Java大神】


※如何快速成長為優秀程序員?高薪程序員必備工具!
※Python 標準庫之 collections 使用教程
TAG:Python開發 |