手动实现把python项目发布为exe可执行程序过程分享


Posted in Python onOctober 23, 2014

1. 手动制作python的exe可执行程序Python没有内建一个编译为exe的功能。给python程序的部署带来不少的麻烦。所以就会出现一些py2exe之类的很不错的工具,用于自动把.py文件编译为.exe文件。

最近抽空研究了一下手动实现类似py2exe的功能,希望加强对python的了解。结果还相当不错。把结果记录下来,与大家共享。

1.1. 原理文中所描述的方法,基于python的以下几个功能 

  1) python程序运行时,会在sys.path指定的路径中查找库文件。 
  2) python从2.3开始,支持从zip文件中import库(支持.py,.pyc和.pyo,但不支持.pyd)
  3) python提供C API,让c语言的程序,可以很方便的调用python的程序

1.2. 实际步骤注:假设python安装在c:\python25目录中,最后的可执行文件放到d:\dist目录中 

  1) 先去c:\python25\Lib目录,把所有文件都复制出来,比如复制到d:\pythonlib目录中
  2) 开一个cmd窗口,进入d:\pythonlib目录中,运行 python -OO compileall.py -f . 把lib中的.py文件都编译成.pyo文件
  3) 删除d:\pythonlib目录中所有的.py和.pyc文件,因为我们只要有.pyo文件就可以让这些库运行了。
  4) 删除目录中所有用不着的文件,比如curses,test,idlelib,msilib等,以减少生成文件的体积。
  5) 把这些库打包成一个zip文件,比如stdlib.zip,放到d:\dist目录中
  6) 把c:\python25\dlls目录中的.pyd和.dll文件,复制到d:\dist\dlls目录中,当然,删除不可能用到的一些文件_msi.pyd,_ssl.pyd等等,可以减少文件的体积
  7) 把自己写的程序,也按步骤2至步骤5所说的方法,打成一个mysrc.zip包,放到d:\dist目录中。 注意:自己写的程序的入口应该是main.pyo文件
  8) 用以下C程序编译出一个可执行文件,比方说叫runpy.exe,也放到d:\dist中。

#include <Python.h>

#include <Windows.h>

#include <stdlib.h>

#include <stdio.h>
int main()

{

       // 得到当前可执行文件所在的目录

       char szPath[10240];

       char szCmd[10240];

       GetModuleFileName(NULL, szPath, sizeof(szPath));

       char* p = strrchr(szPath, '\\');

       if (p == NULL)

       {

            printf("Get module file name error!\n");

            return -1;

       }
       *p = 0;
       // 设定运行时的PATH

       sprintf(szCmd, "PATH=%s\\dlls;%%PATH%%", szPath);

       _putenv(szCmd);
       // 把sys.path设定为['.', '自己的源代码zip文件', '标准库zip文件', 'dll目录']

       // 然后调用main模块

       sprintf(szCmd,

            "import sys\n"

            "sys.path=['.', r'%s\\mysrc.zip', r'%s\\stdlib.zip', r'%s\\dlls']\n"

            "import main\n",

            szPath, szPath, szPath);

      

       Py_OptimizeFlag = 2;

       Py_NoSiteFlag = 1;

       Py_Initialize();

       PyRun_SimpleString(szCmd);

       return 0;

}

9. 把python25.dll放到d:\dist目录中。

结束语

这样来,d:\dist目录中,一共只有4个文件加一个目录:
dlls目录:用于存放所有的dll文件和pyd文件
stdlib.zip文件:用于存放所有的python的.pyo文件格式的标准库
mysrc.zip文件:用于存放自己写的程序。注意,自己写的程序的入口在main.pyo中。
runpy.exe文件:程序的启动文件,启动后会设定python的sys.path,然后调用main模块
python25.dll文件:python的核心dll,runpy.exe依赖于这个dll

--------------------------------------------------------------------------------

哈哈,相当的简洁明了吧。一共才4个文件一个目录,5MB都不到哦。
注:当然,这种打包方式第一次做的时候比较麻烦,但之后就可以只要把自己的程序打包就好了,其它的不用变。
而且,如果自己的程序经常做改动的话,自己的程序也可以不打包,直接放到d:\dist中,反正runpy.exe启动程序的时候,只要能正常运行import main就可以了。

Python 相关文章推荐
跟老齐学Python之网站的结构
Oct 24 Python
处理Python中的URLError异常的方法
Apr 30 Python
django接入新浪微博OAuth的方法
Jun 29 Python
Python守护线程用法实例
Jun 23 Python
python的Crypto模块实现AES加密实例代码
Jan 22 Python
Python Unittest自动化单元测试框架详解
Apr 04 Python
解决python报错MemoryError的问题
Jun 26 Python
pygame游戏之旅 调用按钮实现游戏开始功能
Nov 21 Python
pycharm激活码快速激活及使用步骤
Mar 12 Python
Python连接mysql方法及常用参数
Sep 01 Python
Django创建一个后台的基本步骤记录
Oct 02 Python
浅谈Python从全局与局部变量到装饰器的相关知识
Jun 21 Python
python文件操作整理汇总
Oct 21 #Python
Python中input和raw_input的一点区别
Oct 21 #Python
Python中if __name__ == &quot;__main__&quot;详细解释
Oct 21 #Python
Python创建文件和追加文件内容实例
Oct 21 #Python
python3生成随机数实例
Oct 20 #Python
Python入门篇之面向对象
Oct 20 #Python
Python入门篇之数字
Oct 20 #Python
You might like
PHP使用DOMDocument类生成HTML实例(包含常见标签元素)
2014/06/25 PHP
PHP将字符分解为多个字符串的方法
2014/11/22 PHP
PHP转盘抽奖接口实例
2015/02/09 PHP
php专用数组排序类ArraySortUtil用法实例
2015/04/03 PHP
php两种无限分类方法实例
2015/04/21 PHP
php结合ACCESS的跨库查询功能
2015/06/12 PHP
PHP设置images目录不充许http访问的方法
2016/11/01 PHP
js removeChild 障眼法 可能出现的错误
2009/10/06 Javascript
JavaScript用JQuery呼叫Server端方法示例代码
2014/09/03 Javascript
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
2014/09/13 Javascript
简介BootStrap model弹出框的使用
2016/04/27 Javascript
Vuejs第一篇之入门教程详解(单向绑定、双向绑定、列表渲染、响应函数)
2016/09/09 Javascript
Javascript中函数名.length属性用法分析(对比arguments.length)
2016/09/16 Javascript
在ABP框架中使用BootstrapTable组件的方法
2017/07/31 Javascript
使用jQuery实现购物车结算功能
2017/08/15 jQuery
angular.js和vue.js中实现函数去抖示例(debounce)
2018/01/18 Javascript
详解Vue.js在页面加载时执行某个方法
2018/11/20 Javascript
基于vue.js组件实现分页效果
2018/12/29 Javascript
vue实现的树形结构加多选框示例
2019/02/02 Javascript
javascript判断一个变量是数组还是对象
2019/04/10 Javascript
vue element upload组件 file-list的动态绑定实现
2019/10/11 Javascript
javascript 内存模型实例详解
2020/04/18 Javascript
ES6函数实现排它两种写法解析
2020/05/13 Javascript
从0搭建vue-cli4脚手架
2020/06/17 Javascript
Python多进程通信Queue、Pipe、Value、Array实例
2014/11/21 Python
Python列表切片用法示例
2017/04/19 Python
Python3.6简单操作Mysql数据库
2017/09/12 Python
TensorFLow用Saver保存和恢复变量
2018/03/10 Python
Python hmac模块使用实例解析
2019/12/24 Python
pycharm进入时每次都是insert模式的解决方式
2021/02/05 Python
Bally澳大利亚官网:瑞士奢侈品牌
2018/11/01 全球购物
个人廉洁自律承诺书
2014/03/27 职场文书
小学感恩教育活动总结
2014/07/07 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
安装pytorch时报sslerror错误的解决方案
2021/05/17 Python
MySQL系列之九 mysql查询缓存及索引
2021/07/02 MySQL