Python .py生成.pyd文件并打包.exe 的注意事項(xiàng)說明
最近用python寫了一個(gè)小程序,想發(fā)布出去讓人試用又不想暴露源碼,搜索了一下發(fā)現(xiàn)將py文件編譯成pyd文件就能達(dá)到目的。
轉(zhuǎn)換過程很簡(jiǎn)單,但是在調(diào)用pyd文件并且打包為單個(gè)exe文件的時(shí)候遇到一個(gè)坑,搞了一天才解決,在這里分享一下。
首先安裝cython庫個(gè)人比較喜歡用清華的鏡像庫,速度快。
pip install Cyphton -i https://pypi.tuna.tsinghua.edu.cn/simple然后創(chuàng)建一個(gè)setup.py文件
寫入以下內(nèi)容:
from distutils.core import setupfrom Cython.Build import cythonizesetup(ext_modules=cythonize('BetaV14.py'))BetaV14.py就是要轉(zhuǎn)換為pyd文件的代碼文件
命令行輸入:
python setup.py build_ext --inplace
會(huì)在.py文件目錄下生成一個(gè)BetaV14.cp37-win_amd64.pyd文件,文件名中“.cp37-win_amd64”這一段可以刪除,不刪除也可以正常調(diào)用;但原文件名字段不能改變。
接下來需要打包發(fā)布為.exe文件我用的是pyinstaller,還是用清華鏡像庫安裝。
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple
根據(jù)一些教程,有的說在命令行直接輸入:
pyinstaller -F BetaV14.py
就能直接引用pyd文件打包發(fā)布exe文件,但是在我這里出現(xiàn)文件缺失的錯(cuò)誤:
ValueError: Module file F:python項(xiàng)目1BetaV14.py is missing
繼續(xù)查找問題,發(fā)現(xiàn)需要用一個(gè)入口程序來導(dǎo)入pyd文件,于是創(chuàng)建一個(gè)main.py文件,import剛才生成的模塊,pyd文件默認(rèn)優(yōu)先級(jí)高于py文件,可以在后面解包exe文件來驗(yàn)證。
import BetaV14if __name__ == ’__main__’: BetaV14()
這里需要注意的是程序的__main__入口只能有一個(gè),如果源py文件中有定義main入口,需要注釋掉并調(diào)整代碼縮進(jìn),否則通過main.py調(diào)用pyd文件遇到if name == ‘main’:之后的代碼都不會(huì)運(yùn)行。
接著命令行輸入:pyinstaller -F main.py
打包成.exe文件,在dist目錄下發(fā)現(xiàn)main.exe文件大小只有5M,之前采用py文件打包的程序有接近50M,運(yùn)行之后閃退。這個(gè)問題想了半天才想出來,可能是引用了大量的第三方庫沒有打包進(jìn)去,于是將源py文件頭部import部分全部復(fù)制到main.py文件頭部。
import win32guiimport win32apiimport win32conimport time import randomimport datetimeimport os,sysimport configparserimport numpy as npfrom PIL import Imagefrom scipy.signal import convolve2dimport http.clientimport subprocessimport BetaV14if __name__ == ’__main__’: BetaV14()
再次用命令pyinstaller -F main.py打包,得到正常大小的.exe文件,點(diǎn)擊能正常運(yùn)行。
接下來我們用pyinstxtractor.py(不清楚該腳本是否涉及著作權(quán),請(qǐng)自行搜索)解包exe文件驗(yàn)證一下,命令行輸入:
python pyinstxtractor.py main.exe
會(huì)得到一個(gè)main.exe_extracted文件夾,在文件夾下發(fā)現(xiàn)文件BetaV14.pyd,說明通過引用pyd文件打包成功。
在此作為一個(gè)初學(xué)者記錄一下自己遇到的坑,讓大佬們見笑了。
補(bǔ)充:python打包編譯成pyd或者_(dá)python之setup.py的那些事
今天偶然對(duì)setup.py產(chǎn)生了興趣,以前只知道可以用它來安裝包,例如
python setup.py build ->python setup.py install.當(dāng)然前提你下載的這個(gè)源碼包是壓縮的,之前對(duì)這個(gè)理解并不深,今天偶然看見pip install -e . 的用法,然后串起來想了一下。
我的目錄結(jié)構(gòu)如上,首先我創(chuàng)建了一個(gè)setuptutorial的directory,然后我在下面創(chuàng)建了greet_pkg的python package,并且在setuptutorial下面創(chuàng)建了setup.py如下
from setuptools import setup, find_packages setup( name=’greet’, version=’1.0.0’, packages=find_packages(include=[’greet_pkg’, ’greet_pkg.*’]), url=’’, license=’uestc’, author=’jack’, author_email=’[email protected]’, description=’test package’, py_modules=[’greet2’], install_requires=[’pyjokes’])
greet2.py如下
def greet2(name): print( ’hello’,name,’this is greet2’ )
在greet_pkg下面下了一個(gè)greet.py如下
import pyjokesdef greet(name): print(’hello!’, name, f’im telling you a joke {pyjokes.get_joke()}’)整體目錄結(jié)構(gòu)和setup.py就如上所示
接下來好戲開場(chǎng)了,如果我要在任意其他文件里面使用到我定義的greet()方法,以前的做法是按照import規(guī)則在其他文件里面導(dǎo)入,當(dāng)然如果寫的不規(guī)范,及其的容易出問題,這里我提供另外一個(gè)思路,在setuptutorial下面使用pip install -e . 命令,將setup.py里面包含的package和py_module安裝到Libary root下,當(dāng)然他的實(shí)際的location不是在Libary root下,這個(gè)你可以在pip install -e . 之后使用pip show greet 查看他的信息.
到這里就完了嗎?當(dāng)然沒有,這個(gè)就是之前的python setup.py build 的作用,我這里猜測(cè)大概率是把tar.gz包轉(zhuǎn)化成我上述的目錄結(jié)構(gòu)一樣的directory。
而python setup.py install 的作用就類似于pip install ’-e’ . 。而且python setup.py install 之后的greet包是真的存在于sitepackages里面的。
setup.py除了上述安裝包的作用,還可以是他的逆過程如 python setup.py sdist 成greet.tar.gz,這樣就有上述的裝包的過程先build再install。
還可以使用setup.py將py文件轉(zhuǎn)化為pyd,也可以說將pyx文件轉(zhuǎn)化為pyd,
from setuptools import setup# from distutils.core import setupfrom Cython.Build import cythonize # setup(# name=’hello’,# ext_modules=cythonize([’sayhi.py’])# )
然后運(yùn)行python setup.py build_ext --inplace就可以了!
pyd文件可以很好的隱蔽py文件里面的實(shí)現(xiàn),和linux下的so文件類似。
有類似py->pyd功能的有easycython模塊,可以直接pip安裝。
有人可能會(huì)說pyc也看不見源碼嗎?
但是他可以被反編譯23333
至于如何將py編譯成pyc或pyo
可以使用py_compile或者compileall,不了解的可以自行搜索一下,都有很多的例子,還有針對(duì)pyc的反編譯庫,都可以搜到,至此setup.py我所了解的功能都談完了,里面還有很多參數(shù)可以靈活配置,實(shí)現(xiàn)更加炫酷的效果可以查看這個(gè)鏈接setup.py
相關(guān)文章:
1. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)2. XHTML 1.0:標(biāo)記新的開端3. HTML5 Canvas繪制圖形從入門到精通4. XML解析錯(cuò)誤:未組織好 的解決辦法5. ASP基礎(chǔ)知識(shí)VBScript基本元素講解6. asp(vbscript)中自定義函數(shù)的默認(rèn)參數(shù)實(shí)現(xiàn)代碼7. 詳解CSS偽元素的妙用單標(biāo)簽之美8. 利用CSS3新特性創(chuàng)建透明邊框三角9. 使用Spry輕松將XML數(shù)據(jù)顯示到HTML頁的方法10. XML入門的常見問題(四)
