python原始碼保護之cython

2021-10-07 19:56:31 字數 3926 閱讀 3583

先將py**轉成c**,然後編譯成pyd(window上是pyd,linux上是so)檔案

ubuntu 16.04下:

pip install cython

假設在hello.pyx檔案中的乙個簡單的「hello world」指令碼:

def say_hello_to(name):

print("hello %s!" % name)

注意檔案字尾是pyx

from distutils.core import setup

from cython.build import cythonize

ext_modules=cythonize("hello.pyx"))

根據您使用的python版本,執行:

python setup.py build_ext --inplace

成功構建後,您可以刪除.c和.py檔案,並僅保留.so檔案

#!/usr/bin/env python

from hello import say_hello_to

say_hello_to('mstools')

參考:

環境部署:

整體專案打包指令碼:

#-* -coding: utf-8 -* -

__author__ = 'arvin'

"""執行前提:

系統安裝python-devel 和 gcc

python安裝cython

編譯某個資料夾:

python py2so.py bigomodel

生成結果:

目錄 build 下

生成完成後:

啟動檔案還需要py/pyc擔當,須將啟動的py/pyc拷貝到編譯目錄並刪除so檔案

"""import sys, os, shutil, time

from distutils.core import setup

from cython.build import cythonize

starttime = time.time()

setupfile= os.path.join(os.path.abspath('.'), __file__)

def getpy(basepath=os.path.abspath('.'), parentpath='', name='', build_dir="build",

excepts=(), copyother=false, delc=false):

"""獲取py檔案的路徑

:param basepath: 根路徑

:param parentpath: 父路徑

:param name: 檔案/夾

:param excepts: 排除檔案

:param copy: 是否copy其他檔案

:return: py檔案的迭代器

"""fullpath = os.path.join(basepath, parentpath, name)

for fname in os.listdir(fullpath):

ffile = os.path.join(fullpath, fname)

if os.path.isdir(ffile) and ffile != os.path.join(basepath, build_dir) and not fname.startswith('.'):

for f in getpy(basepath, os.path.join(parentpath, name), fname, build_dir, excepts, copyother, delc):

yield f

elif os.path.isfile(ffile):

# print("\t", basepath, parentpath, name, ffile)

ext = os.path.splitext(fname)[1]

if ext == ".c":

if delc and os.stat(ffile).st_mtime > starttime:

os.remove(ffile)

elif ffile not in excepts and ext not in('.pyc', '.pyx'):

# print("\t\t", basepath, parentpath, name, ffile)

if ext in('.py', '.pyx') and not fname.startswith('__'):

yield os.path.join(parentpath, name, fname)

elif copyother:

dstdir = os.path.join(basepath, build_dir, parentpath, name)

if not os.path.isdir(dstdir): os.makedirs(dstdir)

shutil.copyfile(ffile, os.path.join(dstdir, fname))

else:

pass

if __name__ == "__main__":

currdir = os.path.abspath('.')

parentpath = sys.ar**[1] if len(sys.ar**)>1 else "."

currdir, parentpath = os.path.split(currdir if parentpath == "." else os.path.abspath(parentpath))

build_dir = os.path.join(parentpath, "build")

build_tmp_dir = os.path.join(build_dir, "temp")

print("start:", currdir, parentpath, build_dir)

os.chdir(currdir)

try:

#獲取py列表

module_list = list(getpy(basepath=currdir,parentpath=parentpath, build_dir=build_dir, excepts=(setupfile)))

print(module_list)

setup(ext_modules = cythonize(module_list),script_args=["build_ext", "-b", build_dir, "-t", build_tmp_dir])

module_list = list(getpy(basepath=currdir, parentpath=parentpath, build_dir=build_dir, excepts=(setupfile), copyother=true))

except exception as ex:

print("error! ", ex)

finally:

print("cleaning...")

module_list = list(getpy(basepath=currdir, parentpath=parentpath, build_dir=build_dir, excepts=(setupfile), delc=true))

if os.path.exists(build_tmp_dir): shutil.rmtree(build_tmp_dir)

print("complate! time:", time.time()-starttime, 's')

在要打包的目錄的同級目錄下,建立setup.py,將上述**複製到setup.py, 直接執行setup.py即可。

執行成功後,會出現乙個build資料夾,其中包含有和要打包的專案結構一樣的專案,和原專案不同的是,其中的py檔案(除__init__外)均被打包成pyd檔案,如此原始碼就被保護起來了。

python原始碼剖析 Python原始碼剖析

第頁共 頁python 原始碼剖析 物件機制 1.物件 在python 的世界中,一切都是物件,乙個整數是乙個物件,乙個字串也是 乙個物件,更為奇妙的是,型別也是乙個物件,整數型別是乙個物件,字串類 型也是乙個物件。從 年guido 在那個聖誕節揭開 python 世界的大幕開始,一直到現在,pyt...

Python原始碼學習 之 Python直譯器

include 公有 標頭檔案 lib python編寫的模組 modules c實現的模組 objects 內建物件型別的實現 pc windows下構建python的工程檔案 pcbuild parser 直譯器的 parser tokenizer input handling python 直...

《Python原始碼剖析》之 str

定義 typedef struct pystringobject 說明 pyobject var head pystringobject是變長物件,比定長物件多了乙個ob size欄位 ob shash 儲存字串的hash值,如果還沒計算等於 1 當string hash被呼叫,計算結果會被儲存到這...