对Python3 pyc 文件的使用详解


Posted in Python onFebruary 16, 2019

什么是pyc文件

pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,而且pyc是一种跨平台的字节码,是由python的虚拟机来执行的,这个是类似于JAVA或者.NET的虚拟机的概念。pyc的内容,是跟python的版本相关的,不同版本编译后的pyc文件是不同的,2.5编译的pyc文件,2.4版本的python是无法执行的。

为什么需要pyc文件

这个需求太明显了,因为py文件是可以直接看到源码的,如果你是开发商业软件的话,不可能把源码也泄漏出去吧?所以就需要编译为pyc后,再发布出去。当然,pyc文件也是可以反编译的,不同版本编译后的pyc文件是不同的,根据python源码中提供的opcode,可以根据pyc文件反编译出py文件源码,网上可以找到一个反编译python2.3版本的pyc文件的工具,不过该工具从python2.4开始就要收费了,如果需要反编译出新版本的pyc文件的话,就需要自己动手了(俺暂时还没这能力^--^),不过你可以自己修改python的源代码中的opcode文件,重新编译python,从而防止不法分子的破解。

生成pyc

一、引入模块、包生成

如果模块或包被其他的模块引入后,执行引入模块就会生成pyc文件(被动生成,如果是python2,会在本级目录生,如果是python3的话就在本级目录新建一个__pycache__文件,然后在__pycache__中生成pyc文件)

二、代码编译生成

1. 单个文件

python就是个好东西,它提供了内置的类库来实现把py文件编译为pyc文件,这个模块就是 py_compile 模块。

使用方法非常简单,如下所示,直接在idle中,就可以把一个py文件编译为pyc文件了。

>>> import py_compile
>>> py_compile.compile(r'/Users/zhangyi/Downloads/md5.py')
'/Users/zhangyi/Downloads/__pycache__/md5.cpython-37.pyc'
>>> 
 
Geek-Mac:__pycache__ zhangyi$ ls
md5.cpython-37.pyc

compile函数原型:

compile(file[, cfile[, dfile[, doraise]]])

file 表示需要编译的py文件的路径

cfile 表示编译后的pyc文件名称和路径,默认为直接在file文件名后加c 或者 o,o表示优化的字节码

dfile 这个参数英文看不明白,请各位大大赐教。(鄙视下自己)原文:it is used as the name of the source file in error messages instead of file

doraise 可以是两个值,True或者False,如果为True,则会引发一个PyCompileError,否则如果编译文件出错,则会有一个错误,默认显示在sys.stderr中,而不会引发异常

2. 多个文件

一般来说,我们的工程都是在一个目录下的,一般不会说仅仅编译一个py文件而已,而是需要把整个文件夹下的py文件都编译为pyc文件,python又为了我们提供了另一个模块:compileall 。使用方法如下:

>>> import compileall
>>> compileall.compile_dir(r'/Users/zhangyi/Downloads/MainText')
Listing '/Users/zhangyi/Downloads/MainText'...
Listing '/Users/zhangyi/Downloads/MainText/.idea'...
Listing '/Users/zhangyi/Downloads/MainText/.idea/inspectionProfiles'...
Compiling '/Users/zhangyi/Downloads/MainText/Api.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Block.py'...
Compiling '/Users/zhangyi/Downloads/MainText/JieBa.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Login.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Lxml.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Mat.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Myre.py'...
Compiling '/Users/zhangyi/Downloads/MainText/NLP.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Post.py'...
Compiling '/Users/zhangyi/Downloads/MainText/Text.py'...
Compiling '/Users/zhangyi/Downloads/MainText/get_project_url.py'...
Compiling '/Users/zhangyi/Downloads/MainText/headless_chrome_Test1.py'...
Compiling '/Users/zhangyi/Downloads/MainText/headless_chrome_Test2.py'...
Compiling '/Users/zhangyi/Downloads/MainText/learning.py'...
Compiling '/Users/zhangyi/Downloads/MainText/nsfc.py'...
Compiling '/Users/zhangyi/Downloads/MainText/re.py'...
Compiling '/Users/zhangyi/Downloads/MainText/spider_image.py'...
Compiling '/Users/zhangyi/Downloads/MainText/unit.py'...
True
>>> 
 
Geek-Mac:__pycache__ zhangyi$ pwd
/Users/zhangyi/Downloads/MainText/__pycache__
Geek-Mac:__pycache__ zhangyi$ ls
Api.cpython-37.pyc			Text.cpython-37.pyc
Block.cpython-37.pyc			get_project_url.cpython-37.pyc
JieBa.cpython-37.pyc			headless_chrome_Test1.cpython-37.pyc
Login.cpython-37.pyc			headless_chrome_Test2.cpython-37.pyc
Lxml.cpython-37.pyc			learning.cpython-37.pyc
Mat.cpython-37.pyc			nsfc.cpython-37.pyc
Myre.cpython-37.pyc			re.cpython-37.pyc
NLP.cpython-37.pyc			spider_image.cpython-37.pyc
Post.cpython-37.pyc			unit.cpython-37.pyc
Geek-Mac:__pycache__ zhangyi$

这样就把MainText目录,以及其子目录下的py文件编译为pyc文件了。嘿嘿,够方便吧。来看下compile_dir函数的说明:

compile_dir(dir[, maxlevels[, ddir[, force[, rx[, quiet]]]]])

dir 表示需要编译的文件夹位置

maxlevels 表示需要递归编译的子目录的层数,默认是10层,即默认会把10层子目录中的py文件编译为pyc

ddir 英文没明白,原文:it is used as the base path from which the filenames used in error messages will be generated。

force 如果为True,则会强制编译为pyc,即使现在的pyc文件是最新的,还会强制编译一次,pyc文件中包含有时间戳,python编译器会根据时间来决定,是否需要重新生成一次pyc文件

rx 表示一个正则表达式,比如可以排除掉不想要的目录,或者只有符合条件的目录才进行编译

quiet 如果为True,则编译后,不会在标准输出中,打印出信息

三、通过 Python Shell 命令生成

直接通过命令来运行,可以看到下面的命令中并没有用到compile()函数, 这是因为py_compile模块的main()函数中调用了compile().

python3 -m py_compile md5.py

python3 -O -m py_compile md5.py

-O 优化成字节码

-m 表示把后面的模块当成脚本运行

-OO 表示优化的同时删除文档字符串

如果你想看compile(), compile_dir(), compile_path()具体每个参数是干吗用的,可以使用print py_compile.compile().__doc__来查看,或者直接打开py_compile.py,compileall.py文件来看。

运行pyc文件

直接运行即可!

Geek-Mac:__pycache__ zhangyi$ python3 md5.pyc 
tokenKey ==> 696f6d1af498db3c54ffa572a2723cb7
timeStamp ==> 1530954550
find ==> 100
Geek-Mac:__pycache__ zhangyi$

总结

通过上面的方法,可以方便的把py文件编译为pyc文件了,从而可以实现部分的源码隐藏,保证了python做商业化软件时,保证了部分的安全性吧,继续学习下,看怎么修改opcode。

以上这篇对Python3 pyc 文件的使用详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之字典,你还记得吗?
Sep 20 Python
python中pycurl库的用法实例
Sep 30 Python
win10环境下python3.5安装步骤图文教程
Feb 03 Python
使用XML库的方式,实现RPC通信的方法(推荐)
Jun 14 Python
在IPython中执行Python程序文件的示例
Nov 01 Python
Django中的forms组件实例详解
Nov 08 Python
使用python Telnet远程登录执行程序的方法
Jan 26 Python
Python Gluon参数和模块命名操作教程
Dec 18 Python
基于python实现地址和经纬度转换
May 19 Python
Python爬虫UA伪装爬取的实例讲解
Feb 19 Python
python关于集合的知识案例详解
May 30 Python
浅谈Python数学建模之线性规划
Jun 23 Python
Python父目录、子目录的相互调用方法
Feb 16 #Python
python 获得任意路径下的文件及其根目录的方法
Feb 16 #Python
Python通过for循环理解迭代器和生成器实例详解
Feb 16 #Python
Python3 导入上级目录中的模块实例
Feb 16 #Python
对Python3 goto 语句的使用方法详解
Feb 16 #Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
Feb 16 #Python
Python实现定时自动关闭的tkinter窗口方法
Feb 16 #Python
You might like
解析posix与perl标准的正则表达式区别
2013/06/17 PHP
PHP json_encode() 函数详解及中文乱码问题
2015/11/05 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
javaScript parseInt字符转化为数字函数使用小结
2009/11/05 Javascript
一些javascript一些题目的解析
2010/12/25 Javascript
jquery 无限级下拉菜单的简单实现代码
2014/02/21 Javascript
jQuery复制表单元素附源码分享效果演示
2015/09/30 Javascript
Angular2学习笔记——详解NgModule模块
2016/12/02 Javascript
AJAX和jQuery动态加载数据的实现方法
2016/12/05 Javascript
纯JS实现表单验证实例
2016/12/24 Javascript
vue2.0嵌套路由实现豆瓣电影分页功能(附demo)
2017/03/13 Javascript
bootstrap table动态加载数据示例代码
2017/03/25 Javascript
JavaScript中立即执行函数实例详解
2017/11/04 Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
2018/07/03 jQuery
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
vue通过数据过滤实现表格合并
2020/11/30 Javascript
微信小程序 搜索框组件代码实例
2019/09/06 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
2020/07/18 Javascript
[01:25]DOTA2超级联赛专访iG 将调整状态找回自己
2013/06/05 DOTA
[46:40]VGJ.T vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python文件处理
2016/02/29 Python
python算法演练_One Rule 算法(详解)
2017/05/17 Python
Python机器学习之决策树算法实例详解
2017/12/06 Python
python中有函数重载吗
2020/05/28 Python
python海龟绘图之画国旗实例代码
2020/11/11 Python
电子信息工程自荐信
2014/05/26 职场文书
售房协议书
2014/08/19 职场文书
先进党支部事迹材料
2014/12/24 职场文书
余世维讲座观后感
2015/06/11 职场文书
会议室使用管理制度
2015/08/06 职场文书
中考百日冲刺决心书
2015/09/22 职场文书
2016习总书记系列重要讲话心得体会
2016/01/15 职场文书
《七月的天山》教学反思
2016/02/19 职场文书
什么是css原子化,有什么用?
2022/04/24 HTML / CSS
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android