Python程序编译与反编译

众所周知,Python是纯粹的自由软件, 源代码和解释器CPython遵循 GPL(GNU General Public License)协议。那么很自然会有人有这样的疑问:难道Python程序只能以源代码的方式来运行吗,能不能通过某种方式来保护自己的源代码呢?答案是肯定的。这方面的技术主要有两种:一种方法是把Python程序伪编译成扩展名为.pyc的字节码文件,一种是通过py2exe、pyinstaller或者cx_Freeze对Python程序进行打包。之前的文章:Python安装扩展库与打包成exe可执行文件的方法已经介绍了打包的有关内容,本文主要介绍Python代码编译与反编译。

可以使用py_compile模块的compile()函数或compileall模块的compile_file对Python源程序文件进行编译得到扩展名为.pyc的字节码以提高加载和运行速度,同时还可以隐藏源代码。以Stack.py文件为例,常用的编译方法有(假设已导入py_compile模块):

  • py_compile.compile('Stack.py')

这种形式等价于compileall.compile_file('Stack.py'),也等价于在命令提示符环境中执行命令python -m py_compile Stack.py,都会在Python安装路径下的__pycache__文件夹中生成文件Stack.cpython-35.pyc

  • py_compile.compile('Stack.py', optimize=1)

这种形式等价于compileall.compile_file('Stack.py', optimize=1),也等价于在命令提示符环境中执行命令python -O -m py_compile Stack.py,属于优化编译,会在Python安装路径下的__pycache__文件夹中生成Stack.cpython-35.opt-1.pyc文件。

  • py_compile.compile('Stack.py', optimize=2)

这种形式等价于compileall.compile_file('Stack.py', optimize=2),也等价于在命令提示符环境中执行命令python -OO -m py_compile Stack.py,属于高级优化编译,会在Python安装路径下的__pycache__文件夹中生成文件Stack.cpython-35.opt-2.pyc

此外,Python的compileall模块还提供了compile_dir()和compile_path()等方法,用来支持批量Python源程序文件的编译。

那么问题来了,是不是编译成.pyc文件以后真的无法查看源代码呢?很遗憾,还是有很多办法可以查看的,可以使用Python扩展库uncompyle6或其他类似模块来实现。使用pip工具安装uncompyle6之后,可以使用下面的代码对上面生成的.pyc文件进行反编译得到源代码:

uncompyle6.uncompyle_file('__pycache__\\Stack.cpython-35.opt-1.pyc', open('__pycache__\\Stack.py', 'w'))

另外,http://tool.lu/pyc/这个网站就可以在线上传一个.pyc文件然后立刻得到Python源代码。

原文发布于微信公众号 - Python小屋(Python_xiaowu)

原文发表时间:2016-09-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏orientlu

python 模块与包

每个文件夹对应一个包,包里面可以包含多个包,对应的每个 .py 文件是一个具体模块。 封装成包,在文件上组织好代码后,确保每个目录都要一个 __init__....

15430
来自专栏zhangdd.com

tomcat8 启动报错: ignoring option PermSize=256m处理方法

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=512m; suppor...

18610
来自专栏null的专栏

python技巧——Python的读文件

在Python中,读文件的命令有如下的三个: read() readline() readlines() 1、read()        read()函数是一次...

35440
来自专栏架构师之路

2副图秒懂SQL中的join

废话不多说,直接上图秒懂。 t1表的结构与数据如下: ? t2表的结构与数据如下: ? inner join select * from t1 inner j...

37350
来自专栏Java学习123

Linux下安装配置MemCached(以及libevent)

29380
来自专栏ImportSource

PATH 和 CLASSPATH 的区别

java中的path和classpath是很多java初入者比较困惑的两个变量。本文简单列举二者区别。 PATH and CLASSPATH的区别 1)第一个主...

938120
来自专栏开源项目

Git 项目推荐 | javascript ajax 代理调用工具

javascript ajax 代理调用工具 。 AjaxProxy url: /template/default/script/AjaxProxy.js; 接...

31290
来自专栏Small Code

【Python】numpy 中的 copy 问题详解

这篇文章本是我在 segmentfault 上的一个回答,但是越来越觉得有必要单独拿出来,毕竟这个问题挺常见的。具体可参看 numpy 官方文档 。 正文 nu...

220100
来自专栏架构师之路

30秒懂SQL中的join(2幅图+30秒)

废话不多说,直接上图秒懂。 t1表的结构与数据如下: ? t2表的结构与数据如下: ? inner join select * from t1 inner j...

30470
来自专栏php

Composer常见错误解决

执行composer install遇到错误:Your requirements could not be resolved to an installable...

33000

扫码关注云+社区

领取腾讯云代金券