千家信息网

Python编译相关知识有哪些

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,小编给大家分享一下Python编译相关知识有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Python是一门能快速开发
千家信息网最后更新 2025年02月01日Python编译相关知识有哪些

小编给大家分享一下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_compilepy_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.pycpython 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)

提示

没错,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编译相关知识有哪些"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

编译 文件 模块 字节 源代码 解释 代码 目录 运行 作者 对象 方法 源文件 版本 级别 解释器 保护 生成 源码 脚本 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 原生鸿蒙软件开发 计算机网络技术升本怎么 数据库安全防护系统技术白皮书 sql一次删除百万条数据库 软件编程网络技术培训 软件开发计算机培训学校课程 小程序取得云数据库数据 软件开发项目需要的财务成本 重庆汇农嘉园网络技术有限公司 苹果老是提示无法验证服务器身份 胶州安卓软件开发推荐 找不到网络连接服务器怎么办 靶标 网络安全 epr订制软件开发 我的世界服务器命令方块不能用 山东网络技术转让是真的吗 河南省委网信办网络安全条例 access数据库 页 外包公司软件开发培训 节能网络技术生产厂家 冬奥会网络安全吗 一级网络安全教育多少题 网络安全与中国强军梦 数据库查询例子 凭祥租房软件开发 软件开发如何才能进到大公司 软件开发基础单词 金蝶k3服务器账套管理如何登录 思迅更改数据库 数据库技术在企业中的发展前景
0