最近用python写了一个小程序,想发布出去让人试用又不想暴露源码,搜索了一下发现将py文件编译成pyd文件就能达到目的。
转换过程很简单,但是在调用pyd文件并且打包为单个exe文件的时候遇到一个坑,搞了一天才解决,在这里分享一下。
个人比较喜欢用清华的镜像库,速度快。
pip install Cyphton -i https://pypi.tuna.tsinghua.edu.cn/simple
写入以下内容:
from distutils.core import setup from Cython.Build import cythonize setup(ext_modules=cythonize("BetaV14.py"))
命令行输入:
python setup.py build_ext --inplace
会在.py文件目录下生成一个BetaV14.cp37-win_amd64.pyd文件,文件名中“.cp37-win_amd64”这一段可以删除,不删除也可以正常调用;但原文件名字段不能改变。
我用的是pyinstaller,还是用清华镜像库安装。
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple
根据一些教程,有的说在命令行直接输入:
pyinstaller -F BetaV14.py
就能直接引用pyd文件打包发布exe文件,但是在我这里出现文件缺失的错误:
ValueError: Module file F:\python项目1\BetaV14.py is missing
继续查找问题,发现需要用一个入口程序来导入pyd文件,于是创建一个main.py文件,import刚才生成的模块,pyd文件默认优先级高于py文件,可以在后面解包exe文件来验证。
import BetaV14 if __name__ == '__main__': BetaV14()
这里需要注意的是程序的__main__入口只能有一个,如果源py文件中有定义main入口,需要注释掉并调整代码缩进,否则通过main.py调用pyd文件遇到if name == ‘main':之后的代码都不会运行。
pyinstaller -F main.py
打包成.exe文件,在dist目录下发现main.exe文件大小只有5M,之前采用py文件打包的程序有接近50M,运行之后闪退。这个问题想了半天才想出来,可能是引用了大量的第三方库没有打包进去,于是将源py文件头部import部分全部复制到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文件,点击能正常运行。
接下来我们用pyinstxtractor.py(不清楚该脚本是否涉及著作权,请自行搜索)解包exe文件验证一下,命令行输入:
python pyinstxtractor.py main.exe
会得到一个main.exe_extracted文件夹,在文件夹下发现文件BetaV14.pyd,说明通过引用pyd文件打包成功。
在此作为一个初学者记录一下自己遇到的坑,让大佬们见笑了。
补充:python打包编译成pyd或者_python之setup.py的那些事
今天偶然对setup.py产生了兴趣,以前只知道可以用它来安装包,例如
python setup.py build ->python setup.py install.当然前提你下载的这个源码包是压缩的,之前对这个理解并不深,今天偶然看见pip install -e . 的用法,然后串起来想了一下。
我的目录结构如上,首先我创建了一个setuptutorial的directory,然后我在下面创建了greet_pkg的python package,并且在setuptutorial下面创建了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下面下了一个greet.py如下
import pyjokes def greet(name): print('hello!', name, f'im telling you a joke {pyjokes.get_joke()}')
接下来好戏开场了,如果我要在任意其他文件里面使用到我定义的greet()方法,以前的做法是按照import规则在其他文件里面导入,当然如果写的不规范,及其的容易出问题,这里我提供另外一个思路,在setuptutorial下面使用pip install -e . 命令,将setup.py里面包含的package和py_module安装到Libary root下,当然他的实际的location不是在Libary root下,这个你可以在pip install -e . 之后使用pip show greet 查看他的信息.
当然没有,这个就是之前的python setup.py build 的作用,我这里猜测大概率是把tar.gz包转化成我上述的目录结构一样的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文件转化为pyd,也可以说将pyx文件转化为pyd,
from setuptools import setup # from distutils.core import setup from Cython.Build import cythonize # setup( # name='hello', # ext_modules=cythonize(['sayhi.py']) # )
然后运行python setup.py build_ext --inplace就可以了!
pyd文件可以很好的隐蔽py文件里面的实现,和linux下的so文件类似。
有类似py->pyd功能的有easycython模块,可以直接pip安装。
有人可能会说pyc也看不见源码吗?
但是他可以被反编译23333
至于如何将py编译成pyc或pyo
可以使用py_compile或者compileall,不了解的可以自行搜索一下,都有很多的例子,还有针对pyc的反编译库,都可以搜到,至此setup.py我所了解的功能都谈完了,里面还有很多参数可以灵活配置,实现更加炫酷的效果可以查看这个链接setup.py
iOS IL2CPP打包注意事项 鉴于IL2CPP的特殊性,实际在iOS的发布中可能会遇到一些问题,在这里给大家介绍几个iOS发布时可能会遇到的问题。 IL2CPP和mono的最大区别就是不能在运行时动态生成代码和类型,所以这就要求必须在编译时就完全确定需要用到的类型。 类型裁剪 IL2CPP在打包时会自动对Unity工程的DLL进行裁剪,将代码中没有引用到的类型裁剪掉,以达到减小发布后ipa包的
本文向大家介绍打包PyQt5应用时的注意事项,包括了打包PyQt5应用时的注意事项的使用技巧和注意事项,需要的朋友参考一下 用pyinstaller打包PyQt5项目可能成功,但是在运行打包后的exe时,经常会遇到“ImportError: unable to find Qt5Core.dll on PATH”错误 官方解释,这是PyQt5框架的问题,如何解决? 在所有使用import PyQt5
本文向大家介绍SpringBoot中打war包需要注意事项,包括了SpringBoot中打war包需要注意事项的使用技巧和注意事项,需要的朋友参考一下 最近在做一个项目,遇到了项目打成 war 包的一个问题,项目创建时选择的时 jar 包方式,后因项目部署要求,需要打成 war 包部署,遇到很多坑,在此做一下记录 一、修改打包方式 原: 改后: 二、排除内置 Tomcat 原: 改后: 使用 排除
本文向大家介绍零基础写python爬虫之打包生成exe文件,包括了零基础写python爬虫之打包生成exe文件的使用技巧和注意事项,需要的朋友参考一下 1.下载pyinstaller并解压(可以去官网下载最新版): https://github.com/pyinstaller/pyinstaller/ 2.下载pywin32并安装(注意版本,我的是python2.7): https://pypi.
16.2 集成ORM的注意事项 本节重点介绍适用于所有集成ORM技术的注意事项。在16.3Hibernate一节中提供了很多关于如何配置和使用这些特性提的信息。 Spring对ORM集成的主要目的是使应用层次化,可以任意选择数据访问和事务管理技术,并且为应用对象提供松耦合结构。不再将业务逻辑依赖于数据访问或者事务策略上,不再使用基于硬编码的资源查找,不再使用难以替代的单例,不再自定义服务的注册。同
我试着做一个*。使用pyqtgraph的python应用程序中的exe文件和使用pyinstaller的pyqt库。Pyinstaller生成单个*。exe文件没有错误,但当我尝试启动它时,我得到一个未找到pyqtgraph的错误。 如何构建单个*。使用pyinstaller的exe文件?