上善若水
          In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
          posts - 146,comments - 147,trackbacks - 0

          原文來自:http://wiki.woodpecker.org.cn/moin/LeoJay/PyPackage
          記錄下來以防以后找不到了。

          Python沒有內(nèi)建一個(gè)編譯為exe的功能。給python程序的部署帶來不少的麻煩。

          所以就會(huì)出現(xiàn)一些py2exe之類的很不錯(cuò)的工具,用于自動(dòng)把.py文件編譯為.exe文件。

          最近抽空研究了一下手動(dòng)實(shí)現(xiàn)類似py2exe的功能,希望加強(qiáng)對(duì)python的了解。

          結(jié)果還相當(dāng)不錯(cuò)。把結(jié)果記錄下來,與大家共享。

          原理

           

          文中所描述的方法,基于python的以下幾個(gè)功能

          1. python程序運(yùn)行時(shí),會(huì)在sys.path指定的路徑中查找?guī)煳募?

          2. python從2.3開始,支持從zip文件中import庫(支持.py,.pyc和.pyo,但不支持.pyd)

          3. python提供C API,讓c語言的程序,可以很方便的調(diào)用python的程序

          實(shí)際步驟

           

          注:假設(shè)python安裝在c:\python25目錄中,最后的可執(zhí)行文件放到d:\dist目錄中

          1. 先去c:\python25\Lib目錄,把所有文件都復(fù)制出來,比如復(fù)制到d:\pythonlib目錄中

          2. 開一個(gè)cmd窗口,進(jìn)入d:\pythonlib目錄中,運(yùn)行 python -OO compileall.py -f . 把lib中的.py文件都編譯成.pyo文件

          3. 刪除d:\pythonlib目錄中所有的.py和.pyc文件,因?yàn)槲覀冎灰?pyo文件就可以讓這些庫運(yùn)行了。

          4. 刪除目錄中所有用不著的文件,比如curses,test,idlelib,msilib等,以減少生成文件的體積。

          5. 把這些庫打包成一個(gè)zip文件,比如stdlib.zip,放到d:\dist目錄中

          6. 把c:\python25\dlls目錄中的.pyd和.dll文件,復(fù)制到d:\dist\dlls目錄中,當(dāng)然,刪除不可能用到的一些文件_msi.pyd,_ssl.pyd等等,可以減少文件的體積

          7. 把自己寫的程序,也按步驟2至步驟5所說的方法,打成一個(gè)mysrc.zip包,放到d:\dist目錄中。 注意:自己寫的程序的入口應(yīng)該是main.pyo文件

          8. 用以下C程序編譯出一個(gè)可執(zhí)行文件,比方說叫runpy.exe,也放到d:\dist中。

           

           1#include <Python.h>
           2#include <Windows.h>
           3#include <stdlib.h>
           4#include <stdio.h>
           5
           6int main()
           7{
           8        // 得到當(dāng)前可執(zhí)行文件所在的目錄
           9        char szPath[10240];
          10        char szCmd[10240];
          11        GetModuleFileName(NULL, szPath, sizeof(szPath));
          12        char* p = strrchr(szPath, '\\');
          13        if (p == NULL)
          14        {
          15                printf("Get module file name error!\n");
          16                return -1;
          17        }

          18
          19        *= 0;
          20
          21        // 設(shè)定運(yùn)行時(shí)的PATH
          22        sprintf(szCmd, "PATH=%s\\dlls;%%PATH%%", szPath);
          23        _putenv(szCmd);
          24
          25        // 把sys.path設(shè)定為['.', '自己的源代碼zip文件', '標(biāo)準(zhǔn)庫zip文件', 'dll目錄']
          26        // 然后調(diào)用main模塊
          27        sprintf(szCmd,
          28                "import sys\n"
          29                "sys.path=['.', r'%s\\mysrc.zip', r'%s\\stdlib.zip', r'%s\\dlls']\n"
          30                "import main\n",
          31                szPath, szPath, szPath);
          32        
          33        Py_OptimizeFlag = 2;
          34        Py_NoSiteFlag = 1;
          35        Py_Initialize();
          36        PyRun_SimpleString(szCmd);
          37        return 0;
          38}

          39

           

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

          結(jié)束語

          這樣來,d:\dist目錄中,一共只有4個(gè)文件加一個(gè)目錄:

          • dlls目錄:用于存放所有的dll文件和pyd文件

          • stdlib.zip文件:用于存放所有的python的.pyo文件格式的標(biāo)準(zhǔn)庫

          • mysrc.zip文件:用于存放自己寫的程序。注意,自己寫的程序的入口在main.pyo中。

          • runpy.exe文件:程序的啟動(dòng)文件,啟動(dòng)后會(huì)設(shè)定python的sys.path,然后調(diào)用main模塊

          • python25.dll文件:python的核心dll,runpy.exe依賴于這個(gè)dll


           

          • 哈哈,相當(dāng)?shù)暮?jiǎn)潔明了吧。一共才4個(gè)文件一個(gè)目錄,5MB都不到哦。

          注:當(dāng)然,這種打包方式第一次做的時(shí)候比較麻煩,但之后就可以只要把自己的程序打包就好了,其它的不用變。

          而且,如果自己的程序經(jīng)常做改動(dòng)的話,自己的程序也可以不打包,直接放到d:\dist中,反正runpy.exe啟動(dòng)程序的時(shí)候,只要能正常運(yùn)行import main就可以了。


           

          有不少人寫email給我,問我要我做的包。大家可以在這里下載基于2.5.2版本的包: python_dist.7z 以及基于3.1.2版本的包: python31-dist.7z

          注:3.1.2依賴于visual c++ 2008 redistributable package. 如果在目標(biāo)機(jī)器上沒有安裝,則程序運(yùn)行不起來。

          解開包后,只要用自己的程序替換mysrc.zip就可以使用了。

          包里有runpy.exe和runpyw.exe兩個(gè)文件。其中,runpy.exe是控制臺(tái)程序,runpyw.exe是非控制臺(tái)程序。這兩個(gè)程序分別類似于python.exe和pythonw.exe。想讓程序運(yùn)行時(shí)出現(xiàn)一個(gè)控制臺(tái),就運(yùn)行runpy.exe,如果不想出現(xiàn)黑黑的控制臺(tái),就運(yùn)行runpyw.exe。

           

          posted on 2011-12-20 11:48 DLevin 閱讀(1390) 評(píng)論(0)  編輯  收藏 所屬分類: 收藏
          主站蜘蛛池模板: 东阳市| 富蕴县| 河北省| 和静县| 湾仔区| 东光县| 翁源县| 云阳县| 涞源县| 普宁市| 宁波市| 东阿县| 德保县| 平安县| 吉隆县| 泾源县| 甘孜县| 盐边县| 黄冈市| 分宜县| 铁岭市| 合作市| 库车县| 都江堰市| 禄丰县| 仁寿县| 库伦旗| 小金县| 河西区| 江油市| 根河市| 慈利县| 泾阳县| 行唐县| 万安县| 陆丰市| 新疆| 华池县| 绥芬河市| 牟定县| 平利县|