Python作為解釋型語言,發布即公開源碼,雖然是提倡開源但是有些時候就是忍不住想打包成exe,不僅僅是為了對代碼進行加密,而是為了跨平台。防止有些沒有安裝py環境的電腦無法運行軟件。
目錄對python代碼打包成exe的方式有4種,py2exe,pyinstaller,cx_Freeze,nuitka,分別對以上4種方法介紹,歡迎糾錯和提供新的辦法。
py2exe
介紹
py2exe是一個將python腳本轉換成windows上的可獨立執行的可執行程序(*.exe)的工具,這樣,你就可以不用裝python而在windows系統上運行這個可執行程序。
優點:
可以把python打包成exe
缺點:
打包好的 exe只能在相同的系統下運行,比如你在XP系統用py2exe打包好的exe只能在XP上運行,在win7上肯定有問題,而且也是存在在別的XP機子上也可能不能運行,因為一些別的機子可能會缺少dll文件什么的,作者我當時之所以拋棄py2exe 也是因為這個原因;
打包的文件也需要打包同exe下的dll,和一些庫的壓縮包,不然exe根本跑不起來
打包時候報始終報RuntimeError: BeginUpdateResource錯誤,就需要拷貝dll文件。C:\WINDOWS\system32\python27.dll復制到dist目錄
總之毛病一大堆,基本上已經舍棄了
使用
安裝好后,准備進行打包
准備一個文件x.py,這個x.py就是想要打包成exe。
然后這x.py同目錄下新建一個setup.py,內容如下:
#coding=utf-8 from distutils.core import setup import py2exe includes = ["encodings", "encodings.*"] #要包含的其它庫文件 options = {"py2exe": { "compressed": 1, #壓縮 "optimize": 2, "ascii": 1, "includes": includes, "bundle_files": 1 #所有文件打包成一個exe文件 } } setup ( options = options, zipfile=None, #不生成library.zip文件 console=[{"script": "x.py", "icon_resources": [(1, "Q.ico")] }]#源文件,程序圖標 )
然后這cmd窗口下運行:
python setup.py py2exe
py2exe使用方法 (含一些調試技巧,如壓縮email 類)
pyinstaller
PyInstaller除了win32平台外還支持Linux,Unix平台.py2exe的用法在前面的博文里已經有了,現在看看PyInstaller,pyinstaller是目前應用最多的python打包工具,也是我最常用的。
PyInstaller本身並不是Python模塊,所以安裝時隨便放在哪兒都行。
優點:
可將python文件轉成可執行文件
跨平台
輸出的可以是單一目錄,也可以是一個單獨的打好包的可執行文件。py2exe貌似輸出目錄。
智能支持python的第三方模塊如PyQt,外部數據文件等
支持EGG格式文件
可執行文件可以用UPX壓縮,二進制壓縮方式
支持控制台和視窗兩種方式。
可以選擇exe文件的圖標 (Windows only)
支持 COM server (Windows only)
缺點:
import導入的問題
pyinstaller是很智能的,只要指定了入口py文件,那么它就會根據代碼自動查找需要導入的包。但是隱式導入的話,平常運行是沒有問題的,舉例:
# test1.py from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker DB_CONNECT_STRING = 'mysql+pymysql://root:123456@localhost/study' engine = create_engine(DB_CONNECT_STRING, echo = False) DB_Session = sessionmaker(bind = engine) session = DB_Session() print('this is my test')
運行這個ORM庫的初始化引擎,是沒有問題的,在console得到結果:
this is my test
那么我們開始打包,使用最簡單的pyinstaller test1.py。打包完成后,在當前目錄下有個dist文件夾,進入dist下的test1文件夾,然后打開cmd,運行這個exe,我們就會發現:
提示: no model named ‘pymysql’
這是怎么回事呢?那么問題來了,sqlalchemy這個庫在初始化的時候是不需要顯示導入引擎庫的,它自己有一個create_engine()的函數來初始化,這個字符串是使用者根據規則來自己填寫的。其實解決的方法很簡單,我們只要在顯式導入pymysql這個庫即可。現在我們導入這個庫:
import pymysql
重新打包一遍(重新打包的時候記得刪除掉spec文件,否則會有緩存,或者是加上–clean選項清除掉),再次運行,現在就沒有這個問題了。
多進程打包的問題
官方的CPython存在一個GIL鎖,這個鎖的存在有很多優點,很多庫都是線程安全的,單線程執行的效率也高。在python早期的一個版本中取消掉了GIL,代之以高粒度的鎖來實現多線程,但是實際應用中單個線程的效率大大降低。故后來又將GIL這個鎖還原回去,所以至今的python2也好還是python3中都會有這個鎖。但是這個鎖有很大一個問題,那就是效率問題,它導致了python僅僅只能利用一個core來進行數據的計算。所以后面為了彌補這個GIL帶來的問題,專家們設計了multiprocessing庫,gevent庫等。前一個是多進程庫,為了解決python用於數據密集型處理的情況;后一個用於異步IO處理的情況,基本原理就是在CPU時鍾之間來回切換,簡單的例子就是爬蟲程序爬取網頁的時候。假如有10個url,我們都要去GET它,實際上網絡之間的延遲是大大高於計算機內部的,那么這個時間內計算機就切換到下一個。
有時候運用多進程是必須的,這個替代不了,哪怕它占用資源很多。
使用
安裝:
pip install pyinstaller
使用方法(例子):
pyinstaller -D -p F:\Python27\Lib -i logo.ico mian.py
-D:打包成多個文件
-p:指定python安裝包路徑
-i:指定圖標,我的圖標放在同目錄下
mian.py:要打包的文件,和圖標放在同目錄下了
-D與-F一一對應,-F是打包成一個單獨的文件。最后一排加上–noconsole,就是無窗口運行。
如果py程序是多進程的話,使用pyinstaller打包會出現錯誤,這個時候只要加上一行代碼
在:
if name==‘mian’:
#新增
multiprocessing.freeze_support()
即可
有的時候你加上圖片后打包會出錯,這是因為圖標里面的格式出錯了,需要用圖片編輯軟件重新對圖片內部大小進行設置,這個百度一下吧~
如果要加密混淆代碼(其實沒有用,一樣可以反編譯出你的源代碼,但是聊勝於無吧)
加上一行 --key=asfweakjhfksafkasdkdbas隨便幾個字符串
好像要安裝依賴包,根據提示安裝即可
cx_Freeze
python中比較常用的python轉exe方法有三種,分別是cx_freeze,py2exe,PyInstaller。py2exe恐怕是三者里面知名度最高的一個,但是同時相對來說它的打包質量恐怕也是最差的一個。pyinstaller打包很好,但是操作工序較為復雜,推薦cx_freeze,可以通過pip install cx-freeze 安裝。–這是別人的描述,其實我覺得pyinstaller其實挺簡單的
使用
安裝方法:
打開cmd,輸入pip install cx-freeze 后,會發現在python的Scripts文件夾下生成了三個文件
然后在cmd中,切換到Scripts路徑下,輸入 python cxfreeze-postinstall,會發現Scripts文件夾下又多了.bat文件,此時已經安裝成功
繼續在cmd下嘗試輸入 cxfeeeze -h 驗證下,顯示成功。
提示:直接通過 pip install cx-freeze 安裝,仍然出現錯誤時(找不到文件),最好去官網:網址手動下載相應版本的cx-freeze文件,放在Scripts文件夾下,手動雙擊安裝,然后再運行cxfreeze-postinstall。(例如:我的python版本是3.4.3,下載cx_Freeze-4.3.3.win-amd64-py3.4的文件。注意,版本不對無法安裝!)
在cxfreeze的安裝目錄下即\Python34\Scripts,添加一個文件cxfreeze.bat(可用記事本)cxfreeze.bat內容如下:
@ echo off
C:\Python34\python.exe C:\Python34\Scripts\cxfreeze %*
在該目錄下輸入czfreeze -h也可以查看安裝情況(用pip install cxfreeze就可直接安裝改第三方庫)
打包方法
打包文件時要在Scripts文件夾路徑下操作,文件的路徑最好是絕對路徑。例如:將 G 盤的 hello.py 打包到 G 盤的 123文件夾下:cxfreeze g:\hello.py --taget-dir g:\123 或者 cxfreeze g:\hello.py --taget-dir g:\123 --base-name=Win32GUI。加上–base-name=Win32GUI可以在運行exe時去掉cmd黑框。
具體操作:
首先在命令提示符中使用cd命令轉換到所需要轉換的python文件的目錄中,因為轉換后的dist文件夾會出現在命令提示符的當前目錄中
然后輸入:
cxfreeze --init-script=C:\Users\tangc\Desktop\alien_invasion\alien_invasion.py alien_invasion.py
--init-script=后接絕對路徑
如果你的程序中有圖片等資源,是需要根據程序中的相對路徑加入到dist文件中,也要在.exe同目錄中加入images的文件夾(圖片資源)
如果原.py程序使用了圖片等素材,並且添加圖片是相對路徑(同一個文件夾下可以不使用絕對路徑),打包文件后,需要將圖片等素材拷貝一份放在打包后的文件夾下,否則運行.exe程序會找不到圖片素材。
如果原.py程序使用圖片添加的是絕對路徑,在本地電腦上運行時可能不會發現錯誤。但是你將打包后的文件發給另一台機器,運行.exe程序會報錯,大概意思是“根據你寫的絕對路徑找不到圖片等素材”,即使你在文件夾下拷貝了素材,但是絕對路徑也是錯誤的,所以,最好使用上一種方法。
注意:
只能指定一個要打包的模塊,也就是啟動模塊
發布后,可執行文件執行路徑不能有中文(最好也不要有空格)
啟動執行的文件中不要有下面這種判斷,否則可執行文件執行會沒有任何效果
if __name__=='__mian__':
將exe放到其他機子上運行,彈出“找不到msvcr100.dll“ ,手動將”msvcr100.dll“拷貝到dist目錄下即可
要去掉exe里的后面黑色控制台窗口就在前面的命令改成:
cxfreeze C:\Users\restartRemote.py (需打包文件路徑) –target-dir D:\pyproject (存放exe的目標文件夾路徑)–base-name=win32gui
nuitka
Nuitka直接將python編譯成C++代碼 ,再編譯C++代碼產生可執行文件,完全不存在反向解析的問題,非常安全,而且由於可執行文件由C++編譯而來,運行速度也會獲得提升。
但是我在打包中發現了一個文件,那就是在另一台電腦上無法運行…並且實際編譯時需要近20分鍾,編譯的時候cpu持續100%
不過如果只是自己的電腦上運行的話,還是挺好使的
注意nuitka對python的某些語法有專門要注意的地方
下載完后會提示安裝編譯c++代碼的軟件,使用的是gcc
安裝好有會有一個MinGW64的文件夾,比如我要打包一個back.py的文件,把這個py文件放在哪個目錄下,常用命令如下
python -m nuitka --recurse-all --standalone cc.py python -m nuitka --standalone back.py # 可以用的打包方式 python -m nuitka --recurse-all --recurse-plugins=F:\Python27\Lib --remove-output --plugin-enable=enum_compat back.py # 帶圖標並且有窗口 python -m nuitka --recurse-all --recurse-plugins=F:\Python27\Lib --remove-output --icon=logo.ico --plugin-enable=enum_compat back.py # 不帶窗口不帶圖標 python -m nuitka --recurse-all --recurse-plugins=F:\Python27\Lib --remove-output --plugin-enable=enum_compat --windows-disable-console back.py # 不刪除輔助文件夾 python -m nuitka --recurse-all --recurse-plugins=F:\Python27\Lib --icon=logo.ico --plugin-enable=enum_compat back.py # 其他可運行 python -m nuitka --recurse-all --recurse-plugins=F:\Python27\Lib --standalone --remove-output --icon=logo.ico --plugin-enable=enum_compat back.py
在編譯的時候大概要挺長時間,並且cpu持續暴漲。
速度…感覺確實變快了點…
————————————————
版權聲明:本文為CSDN博主「浪子燕青啦啦啦」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/lzy98/article/details/83246281