當前位置:
首頁 > 知識 > Python 打包分發工具 setuptools 簡介

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開發 的精彩文章:

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

TAG:Python開發 |