Python2.7 版中,只要執行 .py 的檔案後,即會馬上產生一個 .pyc 的檔案,而在 Python3 版中,執行 .py 的檔案後,即會產生一個叫 __pycache__ 的目錄,裡面也會有一個 .pyc 的檔案,就拿剛剛之前的 sys_login.py 來說,當我用 Python3 執行時,就會有一個 __pycache__ 的目錄,裡面就會產生一個檔案叫 sys_login.cpython-35.pyc

那這個檔案有什麼作用呢?

Python 是一門解釋型程式語言?

有人說,Python 是一門解釋性的程式語言,直到發現有 *.pyc 檔案的存在後,開始覺得哪怪怪的,而那個 c 應該指的就是 compiled 的縮寫吧 !!! 為了理清這個問題到底是為什麼,下文會大約介紹一下。

解釋型語言和編譯型語言

電腦是不能夠識別高級語言的,所以當我們運行一個高級語言時,就需要一個 翻譯機 來把高級語言轉變成電腦所能識別機器語言的過程,這個過程就分成二個類型,第一個是編譯型語言,第二種是解釋型語言。

  • 編譯型語言在執行程序之前,會先通過編釋器對程序執行一個編譯的過程,把程序轉變成機器語言,運行時就不需要翻譯,直接就可以執行了,其中最典型的例子就是 C語言

  • 解釋型語言就是不用透過編釋的過程,而是在程序運行時,通過解釋器對程序逐行作出解釋,然後直接運行,最典型的例子就是 RubyPython

總結來說,因為編譯型語言在程序運行之前,就已經對程序做出了翻譯,所以運行中少掉了翻譯的這個動作,所以執行效率比較高一點,但這也不是絕對的,有一些解釋型語言 (Java) 也可以透過解釋器的優化在來對程序做出翻譯時,對整個程序做出優化,從而在效率上超過編譯型語言。

從而在效率上超過編譯型語言 → 這句話不完全正確,應該是說在大多數的情況下,它的速度跟編譯型語言比較接近。此外,隨著 Java語言的興起,我們又不能把語言純粹地分成解釋型語言和編譯型語言。

用 Java 來舉例好了, Java 首先是通過編譯成 Java字節碼文件,然後再運行時通過解釋器給解釋成機器語言,所以我們會說 Java 是一種先編譯後解釋的語言。

Python 到底是什麼呢?

其實 Python和Java、C#是一樣,也是一門基於虛擬機的語言,我們先從表面上簡單地解釋一下 Python 程序的運行過程好了。

當我們在命令行中輸入 python3 hello_world.py 時,其實是觸發了 Python的解釋器 ,告訴 解釋器: Hello, 起床工作啦,別發懶 , 其實 Python 執行的第一項工作跟 Java 一樣,是編釋,只是我們看不到而已。

這是 Java 在命令行中執行一個 Java 程序:

$ javac hello.java

$ java hello

只是我們在使用 intellij 之類的IDE,已經幫我們把先編譯再解釋結合在一起了,而 Python 其實也是一樣執行了這樣的一個過程,所以我們應該說 Python是一門先編譯後解釋的程式語言

簡述 Python 的運行過程

在說這個問題之前,我們先來說二個概念, PyCodeObject和pyc文件

我們在硬碟中看到的 pyc不用多說,其實PyCodeObject就是 Python 編譯器真正編譯成的結果,我們來舉個簡單的例子。

當 Python 程序運行時,編譯的結果會暫時保存在記憶體中的 PyCodeObject中,當 Python 程序結束時,Python解釋器會把PyCodeObject寫入到pyc的檔案裡

當 Python 程序第二次運行時,首先會在硬碟中尋找 .pyc檔,如果有找到,就直接載入,如果沒有找到,就重覆上面的過程。

但還有個問題,如果當 Python 的代碼,如果有做異動的話,那又是怎麼運作的呢?

首先一樣會在硬碟中尋找 .pyc檔,如果有找到,並且發現Python的原始碼有被異動時,就會再檢查時間,而這個時間是指 hello.pyc文件的更新時間和hello.py文件的更新時間相比,假設hello.py的時間比較新,則代表有修改過檔案,則重新編譯,反之,就直接載入,簡單地說就是去判斷二個檔案的更新時間後,再決定到底要不要編譯或是直接載入。

所以我們應該這樣定位 PyCodeObject和pyc文件pyc文件其實是PyCodeObject的一種持久性的保存方式

參考資料:

Python 基礎 - pyc 是什麼的更多相关文章

  1. Python 基礎 - for流程判斷

    今天介紹另一個循環判斷式 for循環,首先,先寫一個很簡單的 for循環的代碼 #!/usr/bin/env python3 # -*- coding:utf-8 -*- for i in range ...

  2. Python 基礎 - if else流程判斷

    hmm~前面講了那麼多,終於可以稍稍的正式進入另一個階段,沒錯,要開始寫判斷式了 這次先從最簡單的判斷式開始,if else 開始- Go 首先,之前有寫有一個簡單的互動式 用戶輸入 的代碼,忘記了嗎 ...

  3. Python 基礎 - 字符編碼

    Python 解釋器在加載 .py 文件中的代碼時,會對內容進行編碼 (默認 ascill) ASCII (American Standard Code for Information Interch ...

  4. Python 基礎 - 數據類型

    標準數據類型 Python3 中有六個標準的數據類型 1 Number(數字) 2 String(字符串) 3 List (列表) 4 Tuple (元組) 5 Sets (集合) 6 Diction ...

  5. Python 基礎 - 認識模塊

    什麼是模塊?簡單說就是別人寫好了一堆功能,封裝在一起. 模塊有分二種,一個是之前有提到的 標準庫,就是不需要透過額外的安裝就有的模塊 ,另一個叫 第三方庫,需要另外安裝才能使用的模塊 #!/usr/b ...

  6. Python 基礎 - 字符轉編碼操作

    回顧字符編碼的前世今生 ASCII 只能儲英文或特殊字符,只占一個字節,一個字節8bit,不能儲中文,所以才出現Unicode Unicode 不管是中文或英文,都是占二個字節,一個字節8bit UT ...

  7. Python 基礎 - 文件操作_v2

    嗯,那如何要把游標的位置給打印來? #!/usr/bin/env python3 # -*- coding:utf-8 -*- f = open('test', 'r') print(f.tell() ...

  8. Python 基礎 - 文件的操作

    在來我們來玩一下文件操作,這個在未來工作上,也是會很常用到的功能 Python2.7中,可以用file()來打開文件,而在Python3中,一律都是用open(),接下來在當前目錄下,先建立一個空文件 ...

  9. Python 基礎 - 字典的操作使用

    接下來介紹字典,這在未來工作上,會是很常使用的,就來好好了解一下唄- 字典是一個 key(鍵)-value(值) 的數據類型,可以儲存很多訊息 #!/usr/bin/env python3 # -*- ...

随机推荐

  1. Java类实例化时候的加载顺序

    面试试题中经常考到此问题,现在做进一步的总结: public class Student { public Student(String name){ System.out.println(name) ...

  2. 让IE7 IE8支持CSS3 background-size属性

    简介 CSS3 新增的 background-size 是一个很有用的属性,用于定义背景图片的尺寸,有了这个属性,你就可以任意指定背景图片的大小.其中最常用的值应该要数 cover 了,该值能让背景图 ...

  3. Android Fragment是什么

    Fragment是Activity中用户界面的一个行为或者一个部分.你可以在一个单独的Activity上把多个Fragment组合成一个多区域的UI,并且可以在多个Activity中使用.你可以认为F ...

  4. java中获取ServletContext常见方法

    http://blog.sina.com.cn/s/blog_3fe961ae0100wjnf.html 1.在javax.servlet.Filter中直接获取 ServletContext con ...

  5. MemCache的LRU删除机制详解

    本节主要讲解一下MC的LRU的删除机制和一些参数的限制 MC的过期数据惰性删除 1.当某个值过期后,并没有从内存中删除,因此,我们在进行st ats统计信息的时候,curr_items有其信息(它的数 ...

  6. 用substr()截取中文出现乱码的解决方法

    截取中文字符串时出现乱码(使用substr()函数) 程序一:PHP截取中文字符串方法 function msubstr($str, $start, $len) {    $tmpstr = &quo ...

  7. xcode7 打开工程错误 This Document requires xcode8.0 or later.

    xcode7 打开工程错误 This Document requires xcode8.0 or later. 场景: xcode7创建的工程,后来安装了xcode8.0,用8打开7的工程跑了一下: ...

  8. GUI 测试

    图形用户界面( GUI )对软件测试提出了有趣的挑战,因为 GUI 开发环境有可复用的构件,开发用户界面更加省时而且更加精确.同时, GUI 的复杂性也增加了,从而加大了设计和执行测试用例的难度.因为 ...

  9. centos 装VBOX

    #cd /etc/yum.repos.d/wget http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repoyum inst ...

  10. PHP数组去重..............过滤字段

    $test_data = M('hot'); //实例化数据表 $data = $test_data->Distinct(true)->field('descriprion')->o ...