我已經瞭解Python是一種解釋型語言......可是,當我查看個人Python源代碼時,我看到.pyc
文件,Windows將其識別爲「編譯的Python文件」。 這些來自哪裏? 後端
Python代碼經歷了兩個階段。 第一步將代碼編譯成.pyc文件,這其實是一個字節碼。 而後使用CPython解釋器解釋此.pyc文件(字節碼)。 請參閱此連接。 這裏用簡單的術語解釋代碼編譯和執行的過程。 緩存
它們包含字節代碼 ,這是Python解釋器編譯源的代碼。 而後,此代碼由Python的虛擬機執行。 字體
Python的文檔解釋了這樣的定義: 優化
Python是一種解釋型語言,與已編譯的語言相反,儘管因爲字節碼編譯器的存在,區別可能很模糊。 這意味着能夠直接運行源文件,而無需顯式建立隨後運行的可執行文件。 spa
這些是由Python解釋器在導入.py
文件時建立的,它們包含導入的模塊/程序的「編譯字節碼」,其思想是從源代碼到字節碼的「轉換」(只須要完成)若是.pyc
比相應的.py
文件更新,則能夠在後續import
跳過一次,從而加快啓動速度。 但它仍然被解釋。 翻譯
我已經理解Python是一種解釋語言...... 指針
這種流行的模因是不正確的,或者更確切地說,是基於對(天然)語言水平的誤解而構建的:相似的錯誤就是說「聖經是精裝書」。 讓我解釋一下比喻...... code
「聖經」是「一本書」,意思是成爲一類 (實際的,物理對象)書籍; 被肯定爲「聖經副本」的書籍應該具備一些基本的共同點(內容,即便是那些可使用不一樣語言,具備不一樣的可接受翻譯,腳註和其餘註釋的水平) - 然而,這些書籍是很好地容許在不被認爲是基本的無數方面有所區別 - 綁定的種類,綁定的顏色,打印中使用的字體,插圖(若是有的話),寬的可寫邊距,內置書籤的數量和種類, 等等等等。 對象
頗有可能的是,聖經的典型印刷確實是精裝書 - 畢竟,它是一本一般意味着一遍又一遍地閱讀的書,在幾個地方加書籤,翻閱尋找給定的章節和詩句指針等等,一個好的精裝書綁定可使給定的副本在這種使用下持續更長時間。 然而,這些是平凡的(實際的)問題,不能用於肯定給定的實際書籍對象是不是聖經的副本:平裝印刷是徹底可能的! 內存
相似地,Python是定義一類語言實現的 「語言」,它必須在某些基本方面都是類似的(語法,大多數語義,除了那些明確容許它們不一樣的那些部分)但徹底容許幾乎每一個「實現」細節都有所不一樣 - 包括他們如何處理他們給出的源文件,他們是否將源代碼編譯成某種較低級別的形式(若是是,那麼哪一種形式 - 以及他們是否保存這些形式編譯表格,磁盤或其餘地方),他們如何執行所述表格,等等。
經典實現CPython一般簡稱爲「Python」 - 但它只是幾個生產質量實現中的一個,與Microsoft的IronPython(編譯爲CLR代碼,即「.NET」)並列,Jython (編譯爲JVM代碼),PyPy(用Python自己編寫,能夠編譯成各類各樣的「後端」形式,包括「即時」生成的機器語言)。 它們都是Python(==「Python語言的實現」),就像許多表面上不一樣的書籍對象均可以是聖經(==「聖經的副本」)。
若是你對CPython特別感興趣:它將源文件編譯成特定於Python的低級表單(稱爲「字節碼」),在須要時自動執行(當沒有與源文件對應的字節碼文件時,或者字節碼文件比源文件舊,或由不一樣的Python版本編譯),一般將字節碼文件保存到磁盤(以免未來從新編譯它們)。 OTOH IronPython一般會編譯爲CLR代碼(將它們保存到磁盤或不依賴)和Jython保存到JVM代碼(將它們保存到磁盤或不保存 - 若是保存它們將使用.class
擴展名)。
而後,這些較低級別的表單由適當的「虛擬機」(也稱爲「解釋器」)執行 - CPython VM,.Net運行時,Java VM(也稱爲JVM)。
所以,從這個意義上來講(典型的實現是作什麼的),當且僅當C#和Java是:全部這些都具備首先生成字節碼的典型實現策略,而後經過VM /解釋器執行它時,Python是一種「解釋語言」 。
更有可能的焦點是編譯過程的「重」,慢和高儀式。 CPython旨在儘量快地編譯,儘量輕量級,儘量少的儀式 - 編譯器執行很是少的錯誤檢查和優化,所以它能夠快速運行而且在少許內存中運行,這樣就能夠了能夠在須要時自動且透明地運行,而無需用戶甚至須要知道正在進行編譯,大多數狀況下。 Java和C#一般在編譯期間接受更多工做(所以不執行自動編譯),以便更完全地檢查錯誤並執行更多優化。 它是灰度級的連續體,而不是黑色或白色的狀況,而且將閾值置於某個給定的水平而且僅在該級別之上將其稱爲「編譯」將是徹底隨意的! - )
Python(至少是它最多見的實現)遵循將原始源代碼編譯爲字節代碼,而後解釋虛擬機上的字節代碼的模式。 這意味着(一樣,最多見的實現)既不是純解釋器也不是純編譯器。
然而,另外一方面,編譯過程大可能是隱藏的 - .pyc文件基本上被視爲緩存; 他們加快了速度,但你一般根本不須要了解它們。 它會根據文件時間/日期戳自動使其無效並從新加載(從新編譯源代碼)。
大約在我看到這個問題的惟一一次是當編譯的字節碼文件以某種方式在將來很好地得到時間戳時,這意味着它老是看起來比源文件更新。 因爲它看起來更新,源文件從未被從新編譯,因此不管你作了什麼改變,它們都會被忽略......