Python .py生成.pyd文件并打包.exe 的注意事項(xiàng)說(shuō)明
最近用python寫(xiě)了一個(gè)小程序,想發(fā)布出去讓人試用又不想暴露源碼,搜索了一下發(fā)現(xiàn)將py文件編譯成pyd文件就能達(dá)到目的。
轉(zhuǎn)換過(guò)程很簡(jiǎn)單,但是在調(diào)用pyd文件并且打包為單個(gè)exe文件的時(shí)候遇到一個(gè)坑,搞了一天才解決,在這里分享一下。
首先安裝cython庫(kù)
個(gè)人比較喜歡用清華的鏡像庫(kù),速度快。
pip install Cyphton -i https://pypi.tuna.tsinghua.edu.cn/simple
然后創(chuàng)建一個(gè)setup.py文件
寫(xiě)入以下內(nèi)容:
from distutils.core import setup from Cython.Build import cythonize setup(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)用;但原文件名字段不能改變。
接下來(lái)需要打包發(fā)布為.exe文件
我用的是pyinstaller,還是用清華鏡像庫(kù)安裝。
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple
根據(jù)一些教程,有的說(shuō)在命令行直接輸入:
pyinstaller -F BetaV14.py
就能直接引用pyd文件打包發(fā)布exe文件,但是在我這里出現(xiàn)文件缺失的錯(cuò)誤:
ValueError: Module file F:\python項(xiàng)目1\BetaV14.py is missing
繼續(xù)查找問(wèn)題,發(fā)現(xiàn)需要用一個(gè)入口程序來(lái)導(dǎo)入pyd文件,于是創(chuàng)建一個(gè)main.py文件,import剛才生成的模塊,pyd文件默認(rèn)優(yōu)先級(jí)高于py文件,可以在后面解包exe文件來(lái)驗(yàn)證。
import BetaV14 if __name__ == '__main__': BetaV14()
這里需要注意的是程序的__main__入口只能有一個(gè),如果源py文件中有定義main入口,需要注釋掉并調(diào)整代碼縮進(jìn),否則通過(guò)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è)問(wèn)題想了半天才想出來(lái),可能是引用了大量的第三方庫(kù)沒(méi)有打包進(jìn)去,于是將源py文件頭部import部分全部復(fù)制到main.py文件頭部。
import win32gui import win32api import win32con import time import random import datetime import os,sys import configparser import numpy as np from PIL import Image from scipy.signal import convolve2d import http.client import subprocess import BetaV14 if __name__ == '__main__': BetaV14()
再次用命令pyinstaller -F main.py打包,得到正常大小的.exe文件,點(diǎn)擊能正常運(yùn)行。
接下來(lái)我們用pyinstxtractor.py(不清楚該腳本是否涉及著作權(quán),請(qǐng)自行搜索)解包exe文件驗(yàn)證一下,命令行輸入:
python pyinstxtractor.py main.exe
會(huì)得到一個(gè)main.exe_extracted文件夾,在文件夾下發(fā)現(xiàn)文件BetaV14.pyd,說(shuō)明通過(guò)引用pyd文件打包成功。
在此作為一個(gè)初學(xué)者記錄一下自己遇到的坑,讓大佬們見(jiàn)笑了。
補(bǔ)充:python打包編譯成pyd或者_(dá)python之setup.py的那些事
今天偶然對(duì)setup.py產(chǎn)生了興趣,以前只知道可以用它來(lái)安裝包,例如
python setup.py build ->python setup.py install.當(dāng)然前提你下載的這個(gè)源碼包是壓縮的,之前對(duì)這個(gè)理解并不深,今天偶然看見(jiàn)pip install -e . 的用法,然后串起來(lái)想了一下。
我的目錄結(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='2444093230@qq.com', 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 pyjokes def greet(name): print('hello!', name, f'im telling you a joke {pyjokes.get_joke()}')
整體目錄結(jié)構(gòu)和setup.py就如上所示
接下來(lái)好戲開(kāi)場(chǎng)了,如果我要在任意其他文件里面使用到我定義的greet()方法,以前的做法是按照import規(guī)則在其他文件里面導(dǎo)入,當(dāng)然如果寫(xiě)的不規(guī)范,及其的容易出問(wèn)題,這里我提供另外一個(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)然沒(méi)有,這個(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除了上述安裝包的作用,還可以是他的逆過(guò)程如 python setup.py sdist 成greet.tar.gz,這樣就有上述的裝包的過(guò)程先build再install。
還可以使用setup.py將py文件轉(zhuǎn)化為pyd,也可以說(shuō)將pyx文件轉(zhuǎn)化為pyd,
from setuptools import setup # from distutils.core import setup from 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ì)說(shuō)pyc也看不見(jiàn)源碼嗎?
但是他可以被反編譯23333
至于如何將py編譯成pyc或pyo
可以使用py_compile或者compileall,不了解的可以自行搜索一下,都有很多的例子,還有針對(duì)pyc的反編譯庫(kù),都可以搜到,至此setup.py我所了解的功能都談完了,里面還有很多參數(shù)可以靈活配置,實(shí)現(xiàn)更加炫酷的效果可以查看這個(gè)鏈接setup.py
相關(guān)文章
Pytorch 搭建分類回歸神經(jīng)網(wǎng)絡(luò)并用GPU進(jìn)行加速的例子
今天小編就為大家分享一篇Pytorch 搭建分類回歸神經(jīng)網(wǎng)絡(luò)并用GPU進(jìn)行加速的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01Python 實(shí)現(xiàn)Windows開(kāi)機(jī)運(yùn)行某軟件的方法
今天小編就為大家分享一篇Python 實(shí)現(xiàn)Windows開(kāi)機(jī)運(yùn)行某軟件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Python進(jìn)階之如何快速將變量插入有序數(shù)組
在我們學(xué)習(xí)python的過(guò)程中,學(xué)習(xí)序列是一門(mén)必修課。本文我們就來(lái)一起看一看Python是如何快速將變量插入有序數(shù)組的,感興趣的可以了解一下2023-04-04Python嵌套函數(shù)與nonlocal使用詳細(xì)介紹
這篇文章主要介紹了Python嵌套函數(shù)與nonlocal使用,nonlocal關(guān)鍵字與global關(guān)鍵字有點(diǎn)相似,可以對(duì)比著理解。nonlocal關(guān)鍵字只能作用域局部變量,且始終找離當(dāng)前最近的上層局部作用域中的變量2022-09-09Numpy中np.random.rand()和np.random.randn() 用法和區(qū)別詳解
這篇文章主要介紹了Numpy中np.random.rand()和np.random.randn() 用法和區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10TensorFlow深度學(xué)習(xí)另一種程序風(fēng)格實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)
這篇文章主要介紹了TensorFlow卷積神經(jīng)網(wǎng)絡(luò)的另一種程序風(fēng)格實(shí)現(xiàn)方式示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11python訪問(wèn)系統(tǒng)環(huán)境變量的方法
這篇文章主要介紹了python訪問(wèn)系統(tǒng)環(huán)境變量的方法,涉及Python操作系統(tǒng)環(huán)境變量的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04python使用wmi模塊獲取windows下的系統(tǒng)信息 監(jiān)控系統(tǒng)
Python用WMI模塊獲取Windows系統(tǒng)的硬件信息:硬盤(pán)分區(qū)、使用情況,內(nèi)存大小,CPU型號(hào),當(dāng)前運(yùn)行的進(jìn)程,自啟動(dòng)程序及位置,系統(tǒng)的版本等信息。2015-10-10python爬蟲(chóng)入門(mén)教程--利用requests構(gòu)建知乎API(三)
這篇文章主要給大家介紹了關(guān)于python爬蟲(chóng)入門(mén)之利用requests構(gòu)建知乎API的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-05-05基于python實(shí)現(xiàn)雪花算法過(guò)程詳解
這篇文章主要介紹了基于python實(shí)現(xiàn)雪花算法過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11