2017-07-10 13:11:54java
https://github.com/Fiz1994python
若是Python 是解釋性語言那麼爲何會存在.pyc 這種文件呢?git
計算機是不可以識別高級語言的,因此當咱們運行一個高級語言程序的時候,就須要一個「翻譯機」來從事把高級語言轉變成計算機能讀懂的機器語言的過程。這個過程分紅兩類,第一種是編譯,第二種是解釋。github
編譯型語言在程序執行以前,先會經過編譯器對程序執行一個編譯的過程,把程序轉變成機器語言。運行時就不須要翻譯,而直接執行就能夠了。最典型的例子就是C語言。緩存
解釋型語言就沒有這個編譯的過程,而是在程序運行的時候,經過解釋器對程序逐行做出解釋,而後直接運行,最典型的例子是Ruby。優化
經過以上的例子,咱們能夠來總結一下解釋型語言和編譯型語言的優缺點,由於編譯型語言在程序運行以前就已經對程序作出了「翻譯」,因此在運行時就少掉了「翻譯」的過程,因此效率比較高。可是咱們也不能一律而論,一些解釋型語言也能夠經過解釋器的優化來在對程序作出翻譯時對整個程序作出優化,從而在效率上超過編譯型語言。編碼
此外,隨着Java等基於虛擬機的語言的興起,咱們又不能把語言純粹地分紅解釋型和編譯型這兩種。spa
用Java來舉例,Java首先是經過編譯器編譯成字節碼文件,而後在運行時經過解釋器給解釋成機器文件。因此咱們說Java是一種先編譯後解釋的語言。命令行
再換成C#,C#首先是經過編譯器將C#文件編譯成IL文件,而後在經過CLR將IL文件編譯成機器文件。因此咱們說C#是一門純編譯語言,可是C#是一門須要二次編譯的語言。同理也可等效運用到基於.NET平臺上的其餘語言。翻譯
當咱們在命令行中輸入python hello.py時,實際上是激活了Python的「解釋器」,告訴「解釋器」:你要開始工做了。但是在「解釋」以前,其實執行的第一項工做和Java同樣,是編譯。
熟悉Java的同窗能夠想一下咱們在命令行中如何執行一個Java的程序:
javac hello.java
java hello
只是咱們在用Eclipse之類的IDE時,將這兩部給融合成了一部而已。其實Python也同樣,當咱們執行python hello.py時,他也同樣執行了這麼一個過程,
先生成了.pyc ,而後加載pyc 文件
因此咱們應該這樣來描述Python,Python是一門先編譯後解釋的語言。
爲了加快加載模塊,Python將每一個模塊的編譯版本緩存在__pycache__目錄下,名稱爲module.version.pyc,其中版本對編譯文件的格式進行編碼;它一般包含Python版本號。例如,在CPython版本3.3中,spam.py的編譯版本將被緩存爲__pycache __ / spam.cpython-33.pyc。這個命名約定容許來自不一樣版本和不一樣版本的Python的編譯模塊共存。
Python根據編譯版本檢查源的修改日期,以查看它是否過時,須要從新編譯。這是一個徹底自動的過程。此外,編譯的模塊與平臺無關,所以能夠在具備不一樣體系結構的系統之間共享相同的庫。
Python在兩種狀況下不檢查緩存。首先,它老是從新編譯而且不存儲直接從命令行加載的模塊的結果。其次,若是沒有源模塊,則不檢查緩存。爲了支持非源(僅編譯)分發,編譯模塊必須位於源目錄中,不能有源模塊。
一些提示:
您能夠在Python命令上使用-O或-OO開關來減少編譯模塊的大小。 -O開關刪除assert語句,-OO開關刪除assert語句和__doc__字符串。因爲一些程序可能依賴於這些可用性,所以若是知道您正在作什麼,則只能使用此選項。 「優化」模塊具備選項標籤,一般較小。將來版本可能會改變優化的效果。
注意:
當從.pyc文件讀取時,程序不會比從.py文件讀取時運行得更快;對於.pyc文件來講,惟一比較快的是它們的加載速度。
模塊compileall能夠爲目錄中的全部模塊建立.pyc文件。
這個過程有更多的細節,包括PEP 3147中決策的流程圖。
具體的能夠查看 這個PEP:
https://www.python.org/dev/pe...
關於這個有不少辦法,你能夠嘗試 py_compile 這個模塊
# -*- coding:utf-8 -*- """ 本身編譯生成.pyc 文件 """ import py_compile import mult py_compile.compile('mult.py') #能夠看到__pycache__ 下mult.cpython-36.pyc生成出來了