Python 基礎 - pyc 是什麼
Python2.7 版中,只要執行 .py 的檔案後,即會馬上產生一個 .pyc 的檔案,而在 Python3 版中,執行 .py 的檔案後,即會產生一個叫 __pycache__ 的目錄,裡面也會有一個 .pyc 的檔案,就拿剛剛之前的 sys_login.py 來說,當我用 Python3 執行時,就會有一個 __pycache__ 的目錄,裡面就會產生一個檔案叫 sys_login.cpython-35.pyc。
那這個檔案有什麼作用呢?
Python 是一門解釋型程式語言?
有人說,Python 是一門解釋性的程式語言,直到發現有 *.pyc 檔案的存在後,開始覺得哪怪怪的,而那個 c 應該指的就是 compiled 的縮寫吧 !!! 為了理清這個問題到底是為什麼,下文會大約介紹一下。
解釋型語言和編譯型語言
電腦是不能夠識別高級語言的,所以當我們運行一個高級語言時,就需要一個 翻譯機 來把高級語言轉變成電腦所能識別機器語言的過程,這個過程就分成二個類型,第一個是編譯型語言,第二種是解釋型語言。
編譯型語言在執行程序之前,會先通過編釋器對程序執行一個編譯的過程,把程序轉變成機器語言,運行時就不需要翻譯,直接就可以執行了,其中最典型的例子就是
C語言。解釋型語言就是不用透過編釋的過程,而是在程序運行時,通過解釋器對程序逐行作出解釋,然後直接運行,最典型的例子就是
Ruby跟Python。
總結來說,因為編譯型語言在程序運行之前,就已經對程序做出了翻譯,所以運行中少掉了翻譯的這個動作,所以執行效率比較高一點,但這也不是絕對的,有一些解釋型語言 (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 是什麼的更多相关文章
- Python 基礎 - for流程判斷
今天介紹另一個循環判斷式 for循環,首先,先寫一個很簡單的 for循環的代碼 #!/usr/bin/env python3 # -*- coding:utf-8 -*- for i in range ...
- Python 基礎 - if else流程判斷
hmm~前面講了那麼多,終於可以稍稍的正式進入另一個階段,沒錯,要開始寫判斷式了 這次先從最簡單的判斷式開始,if else 開始- Go 首先,之前有寫有一個簡單的互動式 用戶輸入 的代碼,忘記了嗎 ...
- Python 基礎 - 字符編碼
Python 解釋器在加載 .py 文件中的代碼時,會對內容進行編碼 (默認 ascill) ASCII (American Standard Code for Information Interch ...
- Python 基礎 - 數據類型
標準數據類型 Python3 中有六個標準的數據類型 1 Number(數字) 2 String(字符串) 3 List (列表) 4 Tuple (元組) 5 Sets (集合) 6 Diction ...
- Python 基礎 - 認識模塊
什麼是模塊?簡單說就是別人寫好了一堆功能,封裝在一起. 模塊有分二種,一個是之前有提到的 標準庫,就是不需要透過額外的安裝就有的模塊 ,另一個叫 第三方庫,需要另外安裝才能使用的模塊 #!/usr/b ...
- Python 基礎 - 字符轉編碼操作
回顧字符編碼的前世今生 ASCII 只能儲英文或特殊字符,只占一個字節,一個字節8bit,不能儲中文,所以才出現Unicode Unicode 不管是中文或英文,都是占二個字節,一個字節8bit UT ...
- Python 基礎 - 文件操作_v2
嗯,那如何要把游標的位置給打印來? #!/usr/bin/env python3 # -*- coding:utf-8 -*- f = open('test', 'r') print(f.tell() ...
- Python 基礎 - 文件的操作
在來我們來玩一下文件操作,這個在未來工作上,也是會很常用到的功能 Python2.7中,可以用file()來打開文件,而在Python3中,一律都是用open(),接下來在當前目錄下,先建立一個空文件 ...
- Python 基礎 - 字典的操作使用
接下來介紹字典,這在未來工作上,會是很常使用的,就來好好了解一下唄- 字典是一個 key(鍵)-value(值) 的數據類型,可以儲存很多訊息 #!/usr/bin/env python3 # -*- ...
随机推荐
- [问题2014S14] 复旦高等代数II(13级)每周一题(第十四教学周)
[问题2014S14] 设 \(V\) 为酉空间, 证明: 不存在 \(V\) 上的非零线性变换 \(\varphi\), 使得对 \(V\) 中任一向量 \(v\) 均有 \[(\varphi(v ...
- C++ string到底是什么
C++ string到底是什么? 要回答这个问题,先要了解什么是basic_string.看一下basic_string的声明: template < class charT, //定义字符串中 ...
- BW常用事务码Tcode
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 和Java相关的一些好文章(不定期更新)
1.Java 集合类详解 (包括arraylist,linkedlist,vector,stack,hashmap,hashtable,treemap,collection等). 2.Java 理论与 ...
- Shell 语法之结构化命令(流程控制)
许多程序在脚本命令之间需要某种逻辑流控制,允许脚本根据变量值的条件或者其他命令的结果路过一些命令或者循环执行这些命令.这些命令通常被称为结构化命令.和其他高级程序设计语言一样,shell提供了用来控制 ...
- GIT warning: LF will be replaced by CRLF.
git config --global core.autocrlf false git config --global core.autocrlf false
- 关于NOR-FLASH和NAND-fLASH的区别。——Arvin
NANDFLASH: Nand-flash内存是flash内存的一种,1989年,东芝公司发表了NAND flash结构.其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案.N ...
- 新建web工程Jdk怎么不是自己安装的, 是自带的
需要在eclipse中配置默认的jdk环境的,不要用它默认的那个,这个不能用的http://blog.csdn.net/clj198606061111/article/details/11881575 ...
- C++ Primer 第九章 顺序容器
由于书籍上写的已经很经典了,故大部分用图片的形式来阐述概念,代码纯手打进行验证. 1.顺序容器类型:vector.deque.list.forword_list.array.string. 2.顺序容 ...
- android mvvm
android studio 需要gradle 1.5.0以上才支持 dependencies { classpath 'com.android.tools.build:gradle:1.5.0'} ...