【Python】 如何用pyinstaller打包python程序成exe


【pyinstaller】

  pyinstaller在他們的官方網站上下載:http://www.pyinstaller.org/

  下載完pyinstaller之后還要安裝一個支持包pywin32. 這個包允許了python訪問windows系統的一些API,如果沒有就會在編譯過程中報錯。

  當然,也可以用pip install pyinstaller來一站式下載pyinstaller和它的支持包。

 

  ■  打包步驟

  用cmd鍵入python ${pyinstaller根目錄}/pyinstaller.py [參數] 入口文件.py即可。入口文件是指當你要打包多個文件為一個exe時的那個程序的入口文件。總之只要你的腳本在IDE或者cmd下是跑得通的那么久可以用pyinstaller來打包成exe。完成后的exe文件在pyinstaller目錄中有一個和入口文件名同名的新目錄,在這個目錄的dist目錄里躺着。

  參數可選:

    --console  在打包成exe后雙擊打開時會帶出控制台來顯示信息

    --windowed  與console相反,在雙擊打開exe后沒有控制台

    --onefile  默認生成的是一個exe作為入口的一大堆文件,用這個參數把這一對文件さらに打包成一個exe,缺點是這個exe往往有點大。。

    --icon='path'  為生成的exe配一個圖標,若不指定則用pyinstaller的默認圖標

    等等.......

  *當打開exe秒退,卻不知道為什么的時候,可以重新用--console參數再編譯一遍,這樣就可以看控制台里輸出的錯誤信息了。

 

  更多參數:(引用自http://www.cnblogs.com/chjbbs/archive/2014/01/25/3533187.html):

  

 ■  pyinstaller的一些坑

  * 我用pyinstaller的幾個項目全都是用wxpython寫的GUI界面項目,然而有好幾次,打包完之后總是會有各種各樣的錯誤導致exe閃退。看了下報錯信息發現錯誤行全部是在文件最上面的import部分。后來發現錯誤原因似乎是在import的時候不能用from wx import *這種形式。至於其他模塊怎么樣不是很清楚が,知道的一點是自己寫的那些腳本當做第三方模塊使用的時候用這種形式是ok的,而碰到wx的時候一定要老老實實import wx然后用wx.Frame之類的方式。。

  * 有幾個程序有登錄服務器的界面,我就加了一個同目錄下生成配置文件,每次登錄界面出現前讀取配置文件,來加載上一次成功登錄時的賬密等信息。但是好幾次在IDE里測試的時候OK的,變成exe之后就不行了。后來發現,原來是腳本的屬性__file__的鍋。在exe中,似乎是不會解釋__file__的,所以導致沒有辦法讀取到當前exe的文件路徑。

 

■  部分環境依賴強的程序打包時碰到各種破問題的解決

  將一些工具從字符界面或者GUI的形式轉化為WEB表現形式似乎是一種很好的選擇。然而WEB編程的時候必然會碰到各種各樣的目錄/相對路徑等等問題。在打包的時候顯得特別難受。

  這么說吧,打包成一個exe雙擊打開之后,其os.path.abspath(__file__)默認是一個建在用戶文件夾中的一個臨時目錄而不是當前程序所在目錄或者cmd中所在目錄(即使你是在這個目錄下運行的程序)。這么一來就使得程序中寫相對路徑找文件肯定是不行的。可以理解成系統將要執行的exe復制到了一個臨時目錄,但是又沒有復制原來exe所在目錄下的其他一些文件,導致找不到文件的錯誤發生。這樣,所有基於__file__的文件補充寫法都會變得無效了 。

  另一種補充文件路徑的寫法是os.getcwd()。這個返回的是工作目錄,所以只要在工作目錄下打開exe程序(這也是一般雙擊打開exe程序的一般做法),就可以在相關目錄下找到相關的文件。在每一個相對路徑前面加上os.getcwd的話雖然比較繁瑣但是可以比較穩地指出所有想要使用的文件的絕對路徑。

  其實更加方便的一種方法就是在一切代碼開始之前就執行以下os.system('cd %s' % os.path.abspath()),把相對目錄的路徑調整到想要到的工作目錄下,這樣后面的相對路徑寫成的文件名就不用改了。

  再補充一下關於flask的,因為上面說的web化GUI或者字符工具我就是用flask做的。flask在尋找templates、static等自帶的項目目錄下的文件夾時並不是簡單地搜尋工作目錄,而是有一套自己的方法。在不修改源碼的前提下,可以考慮flask.Flask()方法加上參數template_folder和static_folder兩個=os.path.join(os.getcwd(),'templates'),os.path.join(os.getcwd(),'static')這樣的方法來做。還有一個常用的擴展是flask_bootstrap,繼承其模板時也會報錯,我沒有去看源碼看它到底是如何尋找模板文件的,而是直接把base.html復制到本項目目錄下然后讓本項目的模板文件繼承。。

 

■  字符問題

  除了上面說到的不能import * 以及相對路徑起點不能用os.path.dirname(os.path.abspath(__file__))而用os.getcwd()以外,還有一點就是編碼的問題。我們腳本中總是習慣性的聲明coding:utf-8,這就導致所有的中文字符都是以utf-8形式編碼。而包裝秤exe之后在dos中運行,通常shell的默認編碼是gbk。所以開發時可以保持coding:utf-8,但是用pyinstaller封裝前最好改成coding:gbk,以防止控制台亂碼的出現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM