中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python編譯相關知識有哪些

發布時間:2021-09-08 14:58:37 來源:億速云 閱讀:103 作者:小新 欄目:大數據

小編給大家分享一下Python編譯相關知識有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Python是一門能快速開發的解釋型語言

Python和Java的解釋方式對比

Java:源代碼 -> 編譯成class -> Jvm解釋運行

Python:源代碼 -> Python解釋器解釋運行

事實上,Python和Java的解釋方式是相同的,只是我們表面上看Python是直接解釋源代碼,而實際上python解釋器只會加載字節碼。細心的小伙伴肯定發現了這一點,當我們import某個模塊時,總是會在模塊所在的目錄創建一個__pycache__目錄,里面存放著被加載模塊的字節碼文件

編譯源代碼有以下作用:

  1. 源代碼保護(算法保護)

  2. 防止用戶篡改源代碼解釋器加載代碼速度加快

Python的幾種文件類型

py:Python控制臺程序的源代碼文件

pyw:Python帶用戶界面的源代碼文件

pyx:Python包源文件

pyc:Python字節碼文件

pyo:Python優化后的字節碼文件

pyd:Python的庫文件(Python版DLL)、在Linux上是so文件

pyc和pyo的生成方法

pyc的作用是用來跨平臺使用的,和Java中的Class文件類似。pyc文件是一種字節碼文件,可以加快Python解釋器的加載速度,當然也可以用來做簡單的防源碼泄露保護。

pyo則是優化過后的字節碼文件,不過pyo更像編譯型語言里的中間文件。

我們可以通過Python提供的py_compile模塊來進行源代碼的編譯。

py_compile模塊只提供3個方法,分別是有關編譯異常PyCompileError、有關編譯compile、有關程序入口main

我們要用到的是compile方法,compile原形如下:

compile(file, cfile=None, dfile=None, doraise=False, optimize=-1)

有5個參數:

file:必選參數,要編譯的源文件

cfile:編譯后的文件,默認在源文件目錄下的__pycache__/源文件名.解釋器類型-python版本.字節碼類型

### 例如:__pycache__/abc.cpython-34.pyo

dfile:錯誤消息文件,默認和cfile一樣

doraise:是否開啟異常處理,默認False

optimize:優化字節碼級別

optimize為1時,優化字節碼級別為最高

-1和0:設置pyc優化級別

1和2:設置pyo優化級別

數字越小,優化級別越高

準備源文件a.py和b.py,內容相同,就是一句print("python")代碼

編寫編譯腳本:

import py_compile

py_compile.compile(file = "a.py",cfile = "a.pyc",optimize=-1)

py_compile.compile(file = "b.py",cfile = "b.pyo",optimize=1)

運行后可以看到已經成功編譯成字節碼文件了,分別為a.pyc和b.pyo。

嘗試運行這2個字節碼文件:

python a.pyc
python a.pyo

字節碼文件成功運行。

也可以直接通過Python加載模塊來運行:

#編譯成pyc

python -m py_compile 源代碼

#編譯成pyo

python -O -m py_compile 源代碼

這確實可以簡單地保護我們的代碼,同時似乎看起來像是加密的效果,但是要注意,這不是加密,只是把源碼變成優化后的字節碼而已,如果想要獲得源碼,我們一樣可以通過逆向編譯來得到源碼,目前有專門逆向Python字節碼的工具存在。

如果需要編譯整個目錄內的所有源代碼,請參考Python compileall

pyd可以讓我們的代碼更安全

如果真的想要保護代碼,為何不考慮把它變成python擴展模塊?(目前還沒有pyd被反編譯的消息)

pyd是Python中的擴展模塊,相當于windows的dll,不同的是pyd只供python調用而已。

實際上,大部分的包、小模塊都是以pyd形式發布的。

如果特別感興趣的小伙伴可以深入研究下setuptools和distutils

在把源代碼轉換成功pyd之前,我們需要用到Cython包。

pip list | findstr "Cython"

檢查是否安裝了Cython,沒有請pip install Cython安裝即可

編譯pyd步驟1:生成C代碼

import Cython.Build

#導入Build模塊

Cython.Build.cythonize("a.py")

#a.py轉換成C代碼

cythonize運行完成之后,無異常的情況下會在a.py的目錄下創建一個a.c文件,同時會返回一個distutils.extension.Extension對象列表

一定要注意的是:如果在Python Shell測試,一定要用絕對路徑,否則會ValueError異常,cythonize不會從sys.path中讀路徑。

編譯pyd步驟2:利用distutils生成pyd擴展模塊

此時我們可以用distutils包來編譯成我們要的pyd模塊

編譯a.py成pyd

import Cython.Build

import distutils.core

a = Cython.Build.cythonize("a.py")

#返回distutils.extension.Extension對象列表

distutils.core.setup(

name = 'pyd的編譯',#包名稱

version = "1.0",#包版本號

ext_modules= a,#擴展模塊

author = "Happyran", #作者

author_email='happyran163@163.com' #作者郵箱

)

python 執行編譯的腳本 build

python 執行編譯的腳本 build_ext

此時會在編譯腳本所在目錄生成一個build目錄,里面存著C語言的.def文件和.o文件,還有我們要的pyd文件

批量編譯pyd文件的誤區

此時我們已經生成了1個pyd文件,如果我們是擴展包/模塊的開發者,怎么批量編譯呢?

總有人會犯錯,例如以下2個例子:

a = Cython.Build.cythonize("a.py")

b = Cython.Build.cythonize("b.py")

distutils.core.setup(

...,

ext_modules= [a,b]

)

這樣做嗎?NO......

a = Cython.Build.cythonize("a.py")

a.append(Cython.Build.cythonize("b.py"))

distutils.core.setup(

...,

ext_modules= a

)

還是這樣?

犯這樣的錯原因卻是因為:

a = Cython.Build.cythonize("a.py")

type(a)

提示<class 'list'>

沒錯,Cython.Build.cythonize返回的是一個列表,里面只有1個distutils.extension.Extension對象

會報錯,需要1個Extension或者是2個元組

批量編譯pyd

方法1:提取我們要的Extension對象

import Cython.Build

import distutils.core

a = Cython.Build.cythonize("a.py")[0] #提取Extension對象

b = Cython.Build.cythonize("b.py")[0]

distutils.core.setup(

name = 'pyd的編譯', #包名稱

version = "1.0", #包版本號

ext_modules= [a,b], #被擴展的模塊

author = "Happyran", #作者

author_email='happyran163@163.com' #作者郵箱

)

方法2:轉換成C代碼后再進行Extension對象實例化

import Cython.Build

import distutils.core

Cython.Build.cythonize("a.py")

Cython.Build.cythonize("b.py")

distutils.core.setup(

name = 'pyd的編譯', #包名稱

version = "1.0", #包版本號

ext_modules= [distutils.core.Extension('a',["a.c"]),distutils.core.Extension('b', ['b.c'])], #被擴展的模塊

#[

#distutils.core.Extension('a',["a.c"]),

#distutils.core.Extension('b', ['b.c'])

#]

author = "Happyran", #作者

author_email='happyran163@163.com' #作者郵箱

)

pyc和pyo相對而言安全性較低,pyd是目前解決Python開發中代碼安全性最優的一個方案。

但是要注意一點:無論是pyc還是pyo、pyd,都是跟著Python版本走的,不要指望Python2.7的東西在Python3上完美運行。

PS:如果遇到running build...提示,刪掉build目錄重新編譯即可。

以上是“Python編譯相關知識有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

延川县| 屏南县| 金昌市| 灵武市| 九台市| 延边| 邵武市| 西峡县| 阿图什市| 磐安县| 射阳县| 奇台县| 潍坊市| 互助| 兴海县| 临朐县| 阳泉市| 屏东县| 遂溪县| 鄂伦春自治旗| 奈曼旗| 蓝山县| 镇宁| 井陉县| 民县| 恩平市| 马龙县| 海晏县| 衡阳市| 科技| 日土县| 甘泉县| 厦门市| 吉安市| 财经| 柳州市| 二连浩特市| 黎川县| 南投市| 金门县| 龙里县|