2012年4月28日 星期六

編譯過的 Compiled Python檔案



對於一些小的程式來說,如果使用很多標準的module,而又想加速啟動的過程,你就可以用編譯過的Python檔案。比如你要找 spam.py ,如果在你找到這個檔案的目錄裡ey4又有一個叫做spam.pyc 的檔案的話,這就表示 spam 這個module有一個已經二元編譯過的(``byte-compiled'')的版本可以使用。在 spam.pyc 裡面也會記錄用來創造它的spam.py上一次被修改的時間,如果 .pyc裡面所儲存的時間與最新版本的 .py 的修改時間不符合的話, .pyc 檔案就不會被使用。
一般來說,你不需要做任何事來創造一個 spam.pyc 檔案。當你成功的編譯一個 spam.py 檔時,自動的 spam.pyc 檔就會寫入在同一個目錄裡。如果這個過程裡有問題的話,系統不會當這是個錯誤情況(error)。相反的,如果寫入的檔案沒有完全成功的寫入的話,這個檔案只會被認為是不正確的而忽視其存在。 spam.pyc 檔案的內容是獨立於作業系統平台的,所以一個 Python module 的目錄是可以被在各種不同架構下的多台機器所共享的。
這裡有一些給專家們的秘訣:

  1. 當使用 -O 這個選項啟動Python直譯器時,直譯器產生會最佳化程式碼
  2. (optimized code),並存在 .pyo 檔案裡。這個最佳化程式碼目前並沒有太多功能,它只是簡單的拿掉所有的 assert 敘述以及 SET_LINENO 指令。當你使用 -O 這個選項時, 所有的 二元碼(bytecode)都會被最佳化,所有的 .pyc 檔都會被忽略,所有的 .py 檔案都會被編譯成最佳化的二元碼。
  3. 如果你傳入兩個 -O 選項給Python直譯器的話 ( -OO) ,在有些很少見的情況下會使得編譯器的最佳化過程使得程式無法正常執行。目前這個選項會使得 __doc__ 字串從二元碼中被拿掉,進而使得 .pyo 檔案可以更精簡。但是有些程式會使用到這些字串,所以你應該只有在你很確定時才使用這個選項。
  4. 讀 .pyc 以及 .pyo 檔案並不會比讀 .py 檔還要快,唯一的差距是在當被導入(load)時的速度有差別。
  5. 當你在命令列(command line)使用script的名稱來執行它的話,並不會造成二元碼被寫到 .pyc 或是 .pyo 所以,你可以把這個script寫成一個module,然後再用一個小的啟動的script來import這個module。這樣可以減少啟動的時間。事實上,你也可以直接從命令列啟動 .pyc 或是 .pyo 檔案。
  6. 你也可以把 spam.pyc (或是 spam.pyo ,如果你用了 -O 的話) 放在沒有 spam.py 的目錄裡。這樣子,當你給別人你的程式庫時,你可以給他們比較難用逆向工程(reverse engineer)破解的程式。
  7. 你可以用 compileall 這個module來將某個目錄裡面的所有module都便成 .pyc 檔案(或者是 .pyo 檔案,如果你用了 -O )。
$ python2.4 -c \
 "from compileall import compile_dir;compile_dir('.')"

Python 標準程式庫的 compileall 模組提供了兩個函式:compile_path 和 compile_dir。
compile_path 很猛,會把 sys.path 裡找得到的所有路徑下的 .py 都編成 .pyc,有點太具侵略性了一點。compile_dir 對 Python 程式寫手可能比較好用點。
在開發 Python 程式的時候,用 compile_dir 可以把任意目錄下的所有 .py 編譯成 .pyc。上述的 command line one liner 會遞迴地把目前目錄下的所有 .py 編譯為 .pyc。應用時機?開發中版本的 web 應用程式 (httpd 使用者與 Python 程式擁有者不同時,因為權限因素,.pyc 是不會自動產生的)。



如何將python專案打包成一個package或者是執行檔的方式呢? 
在 Windows 下有 py2exe
在 Linux/Un*x 下你需要的是 freeze.py



測試編譯: python /path/to/freeze.py [參數] 編譯檔名.py

# python /path/to/freeze.py -o dist test1.py
# cd dist
# make
測試編譯後的linux執行檔
# ./test1

---
錯誤提示:
缺少python2.6/config/config.c.in
安裝以下套件即可
apt-get install python2.6-dev

錯誤提示:
/usr/lib/python2.6/config/libpython2.6.a(posixmodule.o): In function `posix_tmpnam':
(.text+0x783): warning: the use of `tmpnam_r' is dangerous, better use `mkstemp'
/usr/lib/python2.6/config/libpython2.6.a(posixmodule.o): In function `posix_tempnam':
(.text+0x865): warning: the use of `tempnam' is dangerous, better use `mkstemp'
config.o:(.data+0x98): undefined reference to `init_warnings'
collect2: ld returned 1 exit status
make: *** [client] Error 1

安裝以下套件即可
apt-get install ?????

---
安裝 psyco 加速模組
# wget http://downloads.sourceforge.net/project/psyco/psyco/1.6/psyco-1.6-linux.i386-2.5.tar.gz?use_mirror=nchc
# tar xzvf psyco-1.6-linux.i386-2.5.tar.gz
# cd psyco-1.6
# cp -rf psyco /usr/lib/python2.5/site-packages/

#加入 import psyco
try:
    import psyco
    psyco.profile()
except:
    pass

加入psyco模組,再用freeze作編譯,正常可執行

沒有留言:

張貼留言