Python .py生成.pyd文件并打包.exe 的注意事项说明


Posted in Python onMarch 04, 2021

最近用python写了一个小程序,想发布出去让人试用又不想暴露源码,搜索了一下发现将py文件编译成pyd文件就能达到目的。

转换过程很简单,但是在调用pyd文件并且打包为单个exe文件的时候遇到一个坑,搞了一天才解决,在这里分享一下。

首先安装cython库

个人比较喜欢用清华的镜像库,速度快。

pip install Cyphton -i https://pypi.tuna.tsinghua.edu.cn/simple

然后创建一个setup.py文件

写入以下内容:

from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize("BetaV14.py"))

BetaV14.py就是要转换为pyd文件的代码文件

命令行输入:

python setup.py build_ext --inplace

会在.py文件目录下生成一个BetaV14.cp37-win_amd64.pyd文件,文件名中“.cp37-win_amd64”这一段可以删除,不删除也可以正常调用;但原文件名字段不能改变。

接下来需要打包发布为.exe文件

我用的是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 .py生成.pyd文件并打包.exe 的注意事项说明

在此作为一个初学者记录一下自己遇到的坑,让大佬们见笑了。

补充:python打包编译成pyd或者_python之setup.py的那些事

Python .py生成.pyd文件并打包.exe 的注意事项说明

今天偶然对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()}')

整体目录结构和setup.py就如上所示

接下来好戏开场了,如果我要在任意其他文件里面使用到我定义的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

Python 相关文章推荐
跟老齐学Python之玩转字符串(2)更新篇
Sep 28 Python
Python __setattr__、 __getattr__、 __delattr__、__call__用法示例
Mar 06 Python
Python的Tornado框架异步编程入门实例
Apr 24 Python
python实现马耳可夫链算法实例分析
May 20 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
Nov 20 Python
python抓取搜狗微信公众号文章
Apr 01 Python
django 实现将本地图片存入数据库,并能显示在web上的示例
Aug 07 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
Mar 07 Python
python 递归相关知识总结
Mar 03 Python
Python基础详解之邮件处理
Apr 28 Python
Python机器学习之基于Pytorch实现猫狗分类
Jun 08 Python
python脚本框架webpy的url映射详解
Nov 20 Python
python 中 .py文件 转 .pyd文件的操作
Mar 04 #Python
Python实现图片指定位置加图片水印(附Pyinstaller打包exe)
Mar 04 #Python
python 指定源路径来解决import问题的操作
Mar 04 #Python
python源文件的字符编码知识点详解
Mar 04 #Python
python3判断IP地址的方法
Mar 04 #Python
Python解析m3u8拼接下载mp4视频文件的示例代码
Mar 03 #Python
python和opencv构建运动检测器的实现
Mar 03 #Python
You might like
PHP语法速查表
2006/12/06 PHP
php $_SERVER["REQUEST_URI"]获取值的通用解决方法
2010/06/21 PHP
php数组中删除元素的实现代码
2012/06/22 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
2014/06/19 PHP
Laravel模板引擎Blade中section的一些标签的区别介绍
2015/02/10 PHP
用PHP的socket实现客户端到服务端的通信实例详解
2017/02/04 PHP
PHP使用mysqli同时执行多条sql查询语句的实例
2019/03/22 PHP
JS保存、读取、换行、转Json报错处理方法
2013/06/14 Javascript
window.location 对象所包含的属性
2014/10/10 Javascript
深入学习JavaScript中的原型prototype
2015/08/13 Javascript
浅谈使用MVC模式进行JavaScript程序开发
2015/11/10 Javascript
用nodeJS搭建本地文件服务器的几种方法小结
2017/03/16 NodeJs
Angular4 组件通讯方法大全(推荐)
2018/07/12 Javascript
解决layer弹层遮罩挡住窗体的问题
2018/08/17 Javascript
vue实现select下拉显示隐藏功能
2019/09/30 Javascript
你不可不知的Vue.js列表渲染详解
2019/10/01 Javascript
详解vue-router的Import异步加载模块问题的解决方案
2020/05/13 Javascript
Vue页面手动刷新,实现导航栏激活项还原到初始状态
2020/08/06 Javascript
[01:32]完美世界DOTA2联赛10月29日精彩集锦
2020/10/30 DOTA
对python多线程中Lock()与RLock()锁详解
2019/01/11 Python
Python将json文件写入ES数据库的方法
2019/04/10 Python
python time.sleep()是睡眠线程还是进程
2019/07/09 Python
Flask框架钩子函数功能与用法分析
2019/08/02 Python
Python学习之路安装pycharm的教程详解
2020/06/17 Python
Python自动发送和收取邮件的方法
2020/08/12 Python
英国最大的电子零件及配件零售商:Partmaster
2017/04/24 全球购物
莫斯科隐形眼镜网上商店:Linzi
2019/07/22 全球购物
中国包裹转运寄送国际服务:Famiboat
2019/07/24 全球购物
行政人事岗位职责
2014/03/17 职场文书
贸易经济专业自荐书
2014/06/29 职场文书
2014年师德师风工作总结
2014/11/25 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
2015年医院后勤工作总结
2015/05/20 职场文书
装修公司管理制度
2015/08/05 职场文书
2016三严三实专题教育活动心得体会
2016/01/06 职场文书
python如何查找列表中元素的位置
2022/05/30 Python