Python在什么時(shí)候會(huì)生成pyc文件呢?
??事情大概是這樣的,之前我一直以為python文件在執(zhí)行過之后就會(huì)生成pyc文件,后來一次偶然情況下,發(fā)現(xiàn)還是自己too young too simple,在看過其他大神文章并且自己驗(yàn)證之后,發(fā)現(xiàn)還是有點(diǎn)意思的,權(quán)當(dāng)沒事寫點(diǎn)文章吧。
什么是pyc文件呢?
??簡(jiǎn)單來說,pyc文件就是Python的字節(jié)碼文件,我們都知道Python是一種全平臺(tái)的解釋性語言,全平臺(tái)其實(shí)就是Python文件在經(jīng)過解釋器解釋之后(或者稱為編譯)生成的pyc文件可以在多個(gè)平臺(tái)下運(yùn)行,這樣同樣也可以隱藏源代碼。其實(shí),Python是完全面向?qū)ο蟮恼Z言,Python文件在經(jīng)過解釋器解釋后生成字節(jié)碼對(duì)象PyCodeObject,pyc文件可以理解為是PyCodeObject對(duì)象的持久化保存方式。
什么時(shí)候會(huì)生成pyc文件呢?
??pyc文件只有在文件被當(dāng)成模塊導(dǎo)入時(shí)才會(huì)生成。也就是說,Python解釋器認(rèn)為,只有import進(jìn)行的模塊才需要被重用。 生成pyc文件的好處顯而易見,當(dāng)我們多次運(yùn)行程序時(shí),不需要重新對(duì)該模塊進(jìn)行重新的解釋。主文件一般只需要加載一次不會(huì)被其他模塊導(dǎo)入,所以一般主文件不會(huì)生成pyc文件。
??下面來舉個(gè)例子說明,見代碼
文件print_hello.py
print("hello")
import print_hello
執(zhí)行python print_hello.py
E:\test>python print_hello.py
hello
E:\test>dir
驅(qū)動(dòng)器 E 中的卷是 文件
卷的序列號(hào)是 B612-D1B0
E:\test 的目錄
2017/09/25 21:09 <DIR> .
2017/09/25 21:09 <DIR> ..
2017/09/25 21:08 18 import_hello.py
2017/09/25 21:08 14 print_hello.py
2 個(gè)文件 32 字節(jié)
2 個(gè)目錄 49,367,699,456 可用字節(jié)
可以發(fā)現(xiàn)并沒有pyc文件生成,
執(zhí)行python import_hello.py
E:\test>python import_hello.py
hello
E:\test>dir
驅(qū)動(dòng)器 E 中的卷是 文件
卷的序列號(hào)是 B612-D1B0
E:\test 的目錄
2017/09/25 21:12 <DIR> .
2017/09/25 21:12 <DIR> ..
2017/09/25 21:08 18 import_hello.py
2017/09/25 21:08 14 print_hello.py
2017/09/25 21:12 124 print_hello.pyc
3 個(gè)文件 156 字節(jié)
2 個(gè)目錄 49,367,699,456 可用字節(jié)
需要說明兩點(diǎn)的是:
- 執(zhí)行python import_hello.py,開始執(zhí)行import print_hello,導(dǎo)入print_hello模塊,然后執(zhí)行了print_hello模塊里面的代碼,所以我們可以看到有“hello”輸出;
- 如果不想執(zhí)行里面的代碼,一般可以將代碼封裝在一個(gè)類或者函數(shù)里面,然后加個(gè)if判斷,類似下面這樣,表示如果是被導(dǎo)入則不執(zhí)行if下的代碼,如果作為程序入口或者腳本執(zhí)行,則執(zhí)行if下的代碼。
if __name__ == "__main__":
print("hello")
pyc文件的過期時(shí)間
- 在生成pyc文件的同時(shí),寫入了一個(gè)Long型的變量,用于記錄最近修改的時(shí)間;
- 每次載入之前都先檢查一下py文件和pyc文件的最后修改日期,如果不一致則會(huì)生成一個(gè)新的pyc文件
總結(jié)
??總的來說,了解pyc其實(shí)對(duì)于Python開發(fā)者來說并沒有多大的意義,本著鉆研的精神寫下這篇文章,感覺有一下幾點(diǎn)可以考慮
- Python的pyc文件從一定意義上可以減少解釋器解釋Python文件的時(shí)間,不必每次都要解釋編譯一遍,方便下次快速加載,有點(diǎn)類似數(shù)據(jù)庫的緩存吧;
- 想想如果我們想設(shè)計(jì)一個(gè)系統(tǒng),類似主文件這種不會(huì)被重用,而其他模塊可能會(huì)被重用,我們就需要分開設(shè)計(jì)對(duì)待了吧;
- 在設(shè)計(jì)緩存系統(tǒng)時(shí)候,類似Python這種對(duì)比最后修改時(shí)間的方式,是不是可以給我們一點(diǎn)啟示呢?