本篇是關於py2.7.9-docs的FAQ.pdf中關於python編譯的問題“3.13 Can Python be compiled to machine code, C or some other language?”
python不容易被轉化爲機器碼。幾個項目可以證明,它可以轉換爲機器碼,但速度僅提高很少(2倍)。
在內部,python源代碼總是被轉換成字節碼,然後通過python虛擬機去執行。爲了避免重複地解析和轉換很少改變的模塊,這種字節碼被寫到了一個.pyc文件。該pyc文件只有在對應的py文件改變後,纔會重新的進行解析py文件並轉換成字節碼。
pyc文件被加載後,執行它的字節碼和執行py文件明碼沒有性能差異。唯一的區別是加載(import) pyc文件快於加載py文件(因爲還要解析並轉換爲字節碼)。
也就是說,預編譯版本.pyc文件的存在改善了Python腳本的啓動時間,不影響運行時間。如果願意可以手工使用compileall模塊將py文件轉換爲pyc文件。
注意,python執行的主程序腳本不會被(自動)轉換到pyc文件。主程序腳本也同樣會被轉換爲字節碼,但是不會存儲在pyc文件中。主程序(啓動文件)運行,會加載(import)其他的模塊,這時其他的模塊所在路徑下會自動生成對應名稱的pyc文件,但是該啓動文件不會生成pyc。究其原因,大概是主模塊一般不會被其他模塊導入,pyc文件的優勢(被導入時速度快)不會凸顯出來。而且相對較小,即使被導入,也不會造成大的速度消耗。
下面是手工測試的一個場景:
同一個目錄下創建兩個文件,file1.py file2.py,並且在file2中導入file1
#file1.py #coding:utf-8 a = 5 #file2.py #coding:utf-8 import file1
下面運行file2後,發現該目錄下多出了一個file1.pyc文件。
再次運行file2後,發現file1.pyc文件的修改時間是沒有變化的。
修改file1.py文件,比如將a = 5改成 a = 6,保存後運行file2,發現file1.pyc的修改時間變化了
上面的實例即證明了上述的說法,下面簡單使用下compileall模塊:
我們進入cmd,轉入上面實例代碼所在的目錄,然後進入python解釋器,執行:
In [1]: import compileall In [2]: compileall.compile_ compileall.compile_dir compileall.compile_file compileall.compile_path In [2]: compileall.compile_file('file2.py') Compiling file2.py ... Out[2]: 1 In [3]: compileall.compile_dir('./') Listing ./ ... Compiling ./file1.py ... Out[3]: 1 In [4]: