对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中os模块详解
Oct 14 Python
用python实现简单EXCEL数据统计的实例
Jan 24 Python
python模仿网页版微信发送消息功能
Feb 24 Python
详解pandas删除缺失数据(pd.dropna()方法)
Jun 25 Python
Python批量修改图片分辨率的实例代码
Jul 04 Python
Django ModelForm组件使用方法详解
Jul 23 Python
Python 取numpy数组的某几行某几列方法
Oct 24 Python
python实现布隆过滤器及原理解析
Dec 08 Python
解决pip安装的第三方包在PyCharm无法导入的问题
Oct 15 Python
python try...finally...的实现方法
Nov 25 Python
Jupyter Notebook 远程访问配置详解
Jan 11 Python
python实现高效的遗传算法
Apr 07 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
php array_intersect()函数使用代码
2009/01/14 PHP
codeigniter中view通过循环显示数组数据的方法
2015/03/20 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
jquery 最简单易用的表单验证插件
2010/02/27 Javascript
控制页面按钮在后台执行期间不重复提交的JS方法
2013/06/24 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
JavaSciprt中处理字符串之sup()方法的使用教程
2015/06/08 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
jquery单击事件和双击事件冲突解决方案
2016/03/02 Javascript
详解微信小程序Radio选中样式切换
2017/07/06 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
2017/07/19 Javascript
JS如何设置元素样式的方法示例
2017/08/28 Javascript
浅谈js中的this问题
2017/08/31 Javascript
node下使用UglifyJS压缩合并JS文件的方法
2018/03/07 Javascript
微信小程序页面间值传递的两种方法
2018/11/26 Javascript
Vue项目打包部署到iis服务器的配置方法
2019/10/14 Javascript
Vue 修改网站图标的方法
2020/12/31 Vue.js
[33:15]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VP VS Mineski
2018/03/31 DOTA
[55:25]2018DOTA2亚洲邀请赛3月29日 小组赛A组 VG VS OG
2018/03/30 DOTA
Python正则获取、过滤或者替换HTML标签的方法
2016/01/28 Python
使用Python对Access读写操作
2017/03/30 Python
python中类变量与成员变量的使用注意点总结
2017/04/29 Python
python对html过滤处理的方法
2018/10/21 Python
python爬虫 正则表达式解析
2019/09/28 Python
Pytorch Tensor基本数学运算详解
2019/12/30 Python
给Python学习者的文件读写指南(含基础与进阶)
2020/01/29 Python
pytorch使用tensorboardX进行loss可视化实例
2020/02/24 Python
pycharm最新激活码有效期至2100年(亲测可用)
2021/02/05 Python
CSS3中Color的一些特性介绍
2012/05/27 HTML / CSS
荷兰演唱会和体育比赛订票网站:viagogo荷兰
2018/04/08 全球购物
党支部换届选举方案
2014/05/08 职场文书
党建工作整改措施
2014/10/28 职场文书
python多线程方法详解
2022/01/18 Python
Python中npy和mat文件的保存与读取
2022/04/24 Python