python 如何連同依賴打包發布以及python的構建工具?

如我在本機開發一個程序,需要用到python 的mysqldb模塊.我在本地安裝了mysqldb,但是拿到伺服器上去跑也需要安裝這個模塊,有什麼辦發可以不安裝呢?java 里有maven, 很方便直接打成jar包就可以了, 如果用python,在本地安裝好了依賴,怎麼發布呢,挪到別的機器運行也需要按轉這些依賴嗎?

我的目的其實是想在本地構建好開發運行環境,寫好程序後發布,別人不需要安裝我的依賴.

還有就是就是如何搭建開發環境virtualenv, buildout 用什麼工具好?


強烈不建議這樣。

python 的很多庫,內部其實是 C 語言的,使用 easy_install/pip 安裝的時候,往往是下載源碼然後本機編譯的。

如果打包了,可能會出現一些莫名奇妙的問題,比如 32、64 位的兼容問題,不同的操作系統的路徑查找問題,等等。

正確的方式就是在 setup.py 文件中寫明依賴的庫和版本,然後到目標機器上安裝,反正就一句 python setup.py install,不算複雜。


你可以用pip導出你的dependency:

$ pip freeze &> requirements.txt

然後在通過以下命令安裝dependency:

$ pip install -r requirements.txt


  1. 使用 setuptools 來安裝

  2. 使用 buildout 進行構建

下面具體說下這兩點

1. setuptools 的官方文檔在這 setuptools - The PEAK Developers" Center, 當然這份文檔有點長,主要是用來參考。許多 python 項目裡面的 setup.py 就是用的 setuptools,你在 setup.py 裡面只需要寫上依賴的包就 ok,當調用 setup.py install 的時候,會自動幫你把所有依賴包都裝好

2. 構建工具使用 buildout,知乎也在用這個。我曾經使用 virtualenv + pip 的組合,不過這個也還是比較麻煩的。用 buildout 的話,只需要寫一個 buildout.cfg 就可以了,這個是一個 ini 格式的配置文件,一般情況下普通項目也就不到十行配置,真的很少!

你開發完成後,將你的源碼打包發給別人,別人只需要下面兩步就可以把你的代碼依賴搞定(僅限 python 相關的,當然首先,別人得有 python)

python bootstrap.py # 第一次構建需要執行這個腳本來初始化,這個是buildout的初始化腳本
bin/buildout # 當修改了setup.py之後調用,會自動生成需要的腳本

virtualenv + pip 需要怎麼做

本地開發完後,再把代碼給別人之前,需要

pip freeze &> requirements.txt

別人需要做的事情

安裝 virtualenv, virtualenvwrapper, pip

在 .bashrc 中加入

source path/to/virtualenvwrapper.sh
export VENVS=path/to/virtualenv_home

開發前,需要執行下面代碼

mkvirtualenv env
workon env
pip install -r requirements.txt

對比一下,還是有差別的


碰到的了和題主類似的問題,為了方便把寫好的腳本給小白們用,最好是連同依賴打包成單個文件發布。尋求解決方法時看到這個 ? Packaging Python programs as runnable ZIP files James Henstridge ,於是問題解決。

基礎環境有基本的python運行環境,程序依賴的第三方庫底層都是純python實現,python2.6+ /3.* 支持從zip文件運行python代碼。以下所說的方法基於這個前提,如不符,就當我所說的都是幻覺吧。

  1. 在zip文件根目錄創建一個 __main__.py 文件,一個required目錄
  2. 把依賴的非標準模塊從你自己的開發環境下的site-packages下拷貝到zip目錄的required下
  3. 在__main__.py中利用 __file__ 變數拿到執行路徑,拼接出 site-packages 的絕對路徑,添加到 sys.path 中
  4. 然後再載入非標準模塊,執行原本的代碼


pyinstaller就可以做這種事,而且打包好之後,使用方甚至不需要安裝python。其使用非常簡單,甚至就一行命令:

pyinstaller mainscript.py

需要注意的是打包方和使用方必須使用相同的OS,而且如果對方使用不同版本的python,那麼就需要使用相同版本的python進行打包。


用 Python Wheels 可以把依賴項打包到一個 .whl 文件里。

參見:Python Wheels


pip 1.4 提供了 wheel 功能,允許進行二進位包的再分發,我印象上次實驗是可以用來打包 mysqldb 編譯之後結果的。


docker


如果在需要運行的生產環境是離線,斷網的情況下怎麼打包依賴包發布python程序?


目前想到的是docker以及setuptool,只有思路沒有做過


額,雖然沒用過,不過在保證系統環境一樣的情況下,使用上面的方法應該可行


推薦閱讀:

大家常用哪個MySQL客戶端工具,除了命令行那個mysql之外?
如何看待MySQL發布的Group Replication?
怎樣在 MySQL 表中存儲樹形結構數據?
用戶和管理員同時操作同一記錄的不同欄位,如果做並發控制?
MySQL 對於千萬級的大表要怎麼優化?

TAG:Python | 工具 | MySQL |