".pyc"檔案是什麼檔案

Elvin_Chen發表於2015-08-18

轉自:http://lishicongli.blog.163.com/blog/static/14682590201341421211719/

這牽扯出來一個問題:Python是解釋型(interpreted)語言還是編譯型(compiled)語言?

shell我個人得出一個判斷解釋型和編譯型的標準,就是寫兩條語句,一句對,一句錯,看對的一句能不能執行:如果能執行,那就是解釋型(逐行/句/塊解釋,後面的錯不影響前面的執行);如果不能執行,那就是編譯型(因為任何一句有錯誤,將導致編譯不通過)。

>>> def func():

print "hello"

print (x,y)

>>> func()

hello

Traceback (most recent call last):

File "<pyshell#17>", line 1, in <module>

func()

File "<pyshell#16>", line 3, in func

print (x,y)

NameError: global name 'y' is not defined

光看輸出好像是解釋型的樣子,但是正如下面介紹的,Python其實也包含了一個編譯/轉換成中間程式碼(bytecode)的過程。我自己網上查了資料,並沒有一個定論,或許是二者兼而有之吧。這些僅僅摘抄一些觀點:

Python’s high level data types, dynamic typing of objects and run-time invocation of the interpreter (using eval() or exec) together mean that a “compiled” Python program would probably consist mostly of calls into the Python run-time system, even for seemingly simple operations like x+1.)

Python擁有高階資料型別,動態型別和直譯器執行時呼叫,同時還伴隨著一種“編譯的”Python程式(可能由多數的對執行時系統的呼叫組成),即使是“x+1”這樣的簡單操作

Internally, Python source code is always translated into a bytecode representation, and this bytecode is then executed by the Python virtual machine. In order to avoid the overhead of repeatedly parsing and translating modules that rarely change, this byte code is written into a file whose name ends in ”.pyc” whenever a module is parsed. When the corresponding .py file is changed, it is parsed and translated again and the .pyc file is rewritten.)

從內部來看,Python原始碼總是被轉換成bytecode,bytecode之後將會被Python虛擬機器執行。為了避免重複語法解析和轉換那些極少發生改動的模組帶來的overhead,當完成對一個module的語法解析之後,bytecode會被寫入到一個“.pyc”的檔案。而相應的py檔案一旦發生改變(“.py”和“.pyc”是成對出現的,而且是“.pyc”依附於“.py”的關係,如果願意,你也可以刪除”.pyc”檔案,這樣並不會影響結果),對”.py”檔案的再次語法解析和轉換將會導致(與該”.py”檔案)相應的“.pyc”檔案被重寫。

There is no performance difference once the .pyc file has been loaded, as the bytecode read from the .pyc file is exactly the same as the bytecode created by direct translation. The only difference is that loading code from a .pyc file is faster than parsing and translating a .py file, so the presence of precompiled .pyc files improves the start-up time of Python scripts. If desired, the Lib/compileall.py module can be used to create valid .pyc files for a given set of modules.)

一旦”.pyc”檔案被載入,那麼,通過讀取”.pyc”檔案的bytecode來執行和通過轉換成bytecode來執行再效能上並沒有區別。唯一的差異只是從”.pyc”載入bytecode比直接解析轉換一個“.py”檔案要快。也就是說,通過載入預編譯的“.pyc”檔案能夠改進執行Python指令碼的啟動/載入速度。(也就是說,執行bytecode是效率一樣的,唯一的區別就是到bytecode準備好即將開始執行之前。”.pyc”儲存的已經是bytecode,直接載入就可以執行;”.py”需要解析/轉換成bytecode之後才可以執行。)

(Note that the main script executed by Python, even if its filename ends in .py, is not compiled to a .pyc file. It is compiled to bytecode, but the bytecode is not saved to a file. Usually main scripts are quite short, so this doesn’t cost much speed.)

但是也應該注意到,就算直接執行一個”.py”指令碼,雖然沒有編譯成“.pyc”檔案,但是它也會被編譯成bytecode,只是bytecode沒有存入檔案(”.pyc”檔案)中(存在記憶體中)。通常如果指令碼很短的話,對執行速度並沒有大的影響。

相關文章