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

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

首先安装cython库

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

然后创建一个setup.py文件

写入以下内容:

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

命令行输入:

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

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

我用的是pyinstaller,还是用清华镜像库安装。

根据一些教程,有的说在命令行直接输入:

就能直接引用pyd文件打包发布exe文件,但是在我这里出现文件缺失的错误:

valueerror: module file f:\python项目1\betav14.py is missing

继续查找问题,发现需要用一个入口程序来导入pyd文件,于是创建一个main.py文件,import刚才生成的模块,pyd文件默认优先级高于py文件,可以在后面解包exe文件来验证。

这里需要注意的是程序的__main__入口只能有一个,如果源py文件中有定义main入口,需要注释掉并调整代码缩进,否则通过main.py调用pyd文件遇到if name == ‘main’:之后的代码都不会运行。

接着命令行输入:

打包成.exe文件,在dist目录下发现main.exe文件大小只有5m,之前采用py文件打包的程序有接近50m,运行之后闪退。这个问题想了半天才想出来,可能是引用了大量的第三方库没有打包进去,于是将源py文件头部import部分全部复制到main.py文件头部。

再次用命令pyinstaller -f main.py打包,得到正常大小的.exe文件,点击能正常运行。

接下来我们用pyinstxtractor.py(不清楚该脚本是否涉及著作权,请自行搜索)解包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如下

greet2.py如下

在greet_pkg下面下了一个greet.py如下

整体目录结构和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,

然后运行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