談到 Python 的文件后綴,說眼花繚亂也不為過,來看看你遇到過哪些類型! 如果這個(gè)不知道,那請出門左拐,你還是充錢那個(gè)少年,沒有一絲絲改變。接著打游戲去吧… 這個(gè)后綴應(yīng)該算是除了Python 的 py 代碼外,遇到最多的一種文件類型了。 雖然 Python 被普遍認(rèn)為是一種解釋性語言,但誰說它就不能被編譯后執(zhí)行呢? Python 通過 compile 生成的 pyc 文件,然后由 Python 的虛擬機(jī)執(zhí)行,相對于 py 文件來說,編譯成 pyc 本質(zhì)上和 py 沒有太大區(qū)別,只是對于這個(gè)模塊的加載速度提高了,并沒有提高代碼的執(zhí)行速度,通常情況下不用主動(dòng)去編譯 pyc 文件。 那 pyc 文件存在的意義在哪里? 除了略微提高的模塊加載速度外,更多的當(dāng)然是為了一定意義上的保護(hù)源碼不被泄露了。 當(dāng)然為什么說一定意義?因?yàn)榧热挥芯幾g,就畢竟存在反編譯嘍,這個(gè)一會(huì)兒說… 如何將 py 文件編譯成 pyc 文件呢?方法有三: 1、使用 Python 直接編譯 python -m sample.py 2、py_compile
3、compileall import compileall 三種方式一看便知,區(qū)別在于 compileall 可以一次遞歸編譯文件夾下所有的 py 文件 pyo 是源文件優(yōu)化編譯后的文件,pyo 文件在大小上,一般小于等于 pyc 文件。 這個(gè)優(yōu)化沒有多大作用,只是移除了斷言。原文如下:
使用方式:
看到了前幾種,相信 d 這個(gè)字母大家猜猜就能想到,它是 Python的動(dòng)態(tài)鏈接庫;動(dòng)態(tài)鏈接庫( DLL )文件是一種可執(zhí)行文件,允許程序共享執(zhí)行特殊任務(wù)所必需的代碼和其他資源。 你在 Python 安裝目錄的 DLL 文件夾下,就可以看到它們了。 從 Python 3.5 開始,定義了 .pyz 和 .pyzw 分別作為 “Python Zip 應(yīng)用” 和 “Windows 下 Python Zip 應(yīng)用” 的擴(kuò)展名。 新增了內(nèi)置 zipapp 模塊來進(jìn)行簡單的管理,可以用 Zip 打包 Python 程序到一個(gè)可執(zhí)行 .pyz 文件。 使用也比較簡單,但無法想 pyinstaller 等打包 exe 工具一樣脫離 Python 環(huán)境單獨(dú)運(yùn)行,而且這類文件往往拿文本編輯器就能看到它的源碼信息,總體來說還是比較雞肋。 為什么會(huì)再單獨(dú)提到 exe 文件,因?yàn)?Python 有很多可以將 Python 源碼打包成 exe 的工具,從而脫離 Python 環(huán)境單獨(dú)運(yùn)行。 所謂道高一尺魔高一丈,不管是 Python、JAVA 還是 C 語言,只要有編譯,必然存在反編譯的操作。 不管再怎么去考慮加密,勢必都有人能破解,只是成本不同而已,所以編譯只可作為一種防君子不防小人的操作。 今天主要和大家聊聊 pyc 文件的反編譯,其中有哪些小心機(jī)的做法與陷阱。 首先,反編譯既然是一種非正常手段,Python 自然不會(huì)原生附帶該模塊。 我們需要先安裝依賴: # 安裝依賴 操作也比較簡單,命令行下輸入:
這就完了?說好的心機(jī)與陷阱呢?哈哈,接著看… 使用注釋的心機(jī)我們來創(chuàng)建一個(gè)名為 BreezePython.py 的文件,并將下面的代碼進(jìn)行編譯和反編譯,來看看反編譯后的內(nèi)容與原始代碼有什么差異 import platform 編譯:
反編譯: uncompyle6 BreezePython.cpython-37.pyc > output.py 下來看看反編譯后的文件有什么區(qū)別吧:
相比于原始的代碼,有什么差別? 沒錯(cuò),注釋…文檔注釋默認(rèn)會(huì)保留,但使用# 進(jìn)行的注釋,卻在編譯+反編譯的過程中丟失了。 那么如果你是個(gè)心機(jī) boy,代碼注釋都用#去寫吧,即便反編譯了代碼,沒有注釋的情況下,即便我們自己也會(huì)被大段沒有注釋的代碼搞瘋掉了,哈哈。 反編譯就萬無一失么?NO…舉一個(gè)例子吧,這段代碼隨意而為,只是為了讓反編譯的時(shí)候拋出錯(cuò)誤: class Demo: 正常情況這段代碼應(yīng)該返回:get None…
編譯后的代碼返回:I'm True,I like white best 什么鬼?這編譯成什么了亂七八糟的了東西了。 根據(jù)多年采坑經(jīng)驗(yàn),反編譯的代碼,當(dāng)遇到多個(gè)if not 的時(shí)候,最后一個(gè) if not 就會(huì)被所謂的簡要寫法而弄巧成拙,最終導(dǎo)致反編譯出錯(cuò)。 這個(gè)是個(gè)坑,同樣你是否也可以利用它呢? 今天的文章就到這里,希望通過這篇文章能讓你對 Python 的文件類型與編譯、反編譯操作有所了解。如果有收獲,期待你的支持與轉(zhuǎn)發(fā)。 |
|