1 - Python编译过程涉及的文件

py

源代码文件,由python.exe解释,可在控制台下运行,可用文本编辑器进行编辑;

pyc

源代码文件经过编译后生成的二进制文件,无法用文本编辑器进行编辑;

执行一个.py文件后,并不会自动生成对应的.pyc文件,需要指定触发Python来创建pyc文件;

- pyc是由py文件经过编译后生成的二进制字节码(byte code)文件;

- pyc文件的加载速度比py文件快;

- pyc文件是一种跨平台的字节码,由python的虚拟机来执行;

- pyc文件的内容跟python版本相关,不同的python版本编译生成不同的pyc文件,只能在相同版本环境下执行;

pyo

源代码文件经过优化编译后生成的文件,无法用文本编辑器进行编辑;

Python3.5之后,不再使用.pyo文件名,而是使用类似“xxx.opt-n.pyc的文件名;

pyd

是python的动态链接库;

动态链接库(DLL)文件是一种可执行文件,允许程序共享执行特殊任务所必需的代码和其他资源;

pyd文件虽然是作为python的动态模块,但实质上还是DLL文件,只是后缀改为pyd;

一般是用C、C++、D语言按照一定的格式编写;

参考信息:https://docs.python.org/3/faq/windows.html?highlight=pyd#is-a-pyd-file-the-same-as-a-dll

pyz

从Python 3.5开始,定义了.pyz和.pyzw分别作为“Python Zip应用”和“Windows下Python Zip应用”的扩展名。

新增了内置zipapp模块来进行简单的管理,可以用Zip打包Python程序到一个可执行.pyz文件。

- zipapp — Manage executable python zip archives

- https://docs.python.org/3/library/zipapp.html

详细内容请见PEP441(https://www.python.org/dev/peps/pep-0441/)

2 - 生成pyc文件

执行一个.py文件后,并不会自动生成对应的.pyc文件,需要指定触发Python来创建pyc文件。

可以利用Python的import机制创建pyc文件:

内置的py_compile模块可以把py文件编译为pyc或pyo文件;

内置的compileall模块可以把整个目录中的py文件编译为pyc或pyo文件;

生成pyc文件的过程:

Python在执行import语句时(例如“import abc”),将会到已设定的path中寻找abc.pyc或abc.dll文件。

如果只是发现了abc.py,那么Python会首先将abc.py编译成相应的PyCodeObject中间结果,然后创建abc.pyc文件,并将中间结果写入该文件。

然后,Python会import这个abc.pyc文件,实际上也就是将abc.pyc文件中的PyCodeObject重新在内存中复制出来。

生成pyc文件的方法:

命令形式:

python -m py_compile file.py # 生成单个pyc文件

python -m py_compile /dir/{file1,file2}.py # 生成多个pyc文件

python -m compileall /dir/ # 生成目录下所有py文件对应的pyc文件

脚本形式:compile模块的compile函数

import py_compile # 相当于命令行中的“-m py_compile”

py_compile.compile('py file path')

脚本形式:compileall模块的compile_dir函数

import compileall

compileall.compile_dir("py files dir")

生成pyc文件示例:

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 2

-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py

-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ cat sample.py

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

print("Hello Python !")

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ cat sample2.py

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

print("Hello World !")

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ python -m compileall ./

Listing './'...

Compiling './sample.py'...

Compiling './sample2.py'...

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 6

drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/

-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py

-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l __pycache__/

total 2

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc

3 - 生成pyo文件

与生成pyc文件类似,但要额外使用-O和-OO选项来生成pyo文件。

但在Python3.5之后,不再使用.pyo文件名,而是生成文件名类似“xxx.opt-n.pyc的文件。

命令示例:

python -O -m py_compile file.py

python -O -m py_compile /dir/{file1,file2}.py

python -O -m compileall /dir/

示例:python3.6生成pyo文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ python -O -m compileall ./

Listing './'...

Compiling './sample.py'...

Compiling './sample2.py'...

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l __pycache__/

total 4

-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample.cpython-36.opt-1.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample2.cpython-36.opt-1.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc

示例:python2.7生成pyo文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 6

drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/

-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py

-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ py -2 -O -m compileall ./

Listing ./ ...

Listing ./__pycache__ ...

Compiling ./sample.py ...

Compiling ./sample2.py ...

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 8

drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/

-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample.pyo

-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample2.pyo

4 - 运行pyc或pyo文件

运行pyc文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample.cpython-36.pyc

Hello Python !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample2.cpython-36.pyc

Hello World !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample.cpython-36.opt-1.pyc

Hello Python !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ python sample2.cpython-36.opt-1.pyc

Hello World !

运行pyo文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 8

drwxr-xr-x 1 anliven 197121 0 3月 7 23:42 __pycache__/

-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample.pyo

-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample2.pyo

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ py -2 sample.pyo

Hello Python !

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ py -2 sample2.pyo

Hello World !

5 - 利用uncompyle6进行Python反编译

uncompyle6

安装uncompyle6

$ pip3 install --proxy="10.144.1.10:8080" uncompyle6

Collecting uncompyle6

Downloading uncompyle6-3.0.0-py36-none-any.whl (195kB)

100% |████████████████████████████████| 204kB 321kB/s

Requirement already satisfied: six in c:\python36\lib\site-packages (from uncompyle6)

Collecting spark-parser<1.9.0,>=1.8.5 (from uncompyle6)

Downloading spark_parser-1.8.5-py36-none-any.whl

Collecting xdis<3.7.0,>=3.6.9 (from uncompyle6)

Downloading xdis-3.6.11-py36-none-any.whl (74kB)

100% |████████████████████████████████| 81kB 153kB/s

Collecting click (from spark-parser<1.9.0,>=1.8.5->uncompyle6)

Using cached click-6.7-py2.py3-none-any.whl

Installing collected packages: click, spark-parser, xdis, uncompyle6

Successfully installed click-6.7 spark-parser-1.8.5 uncompyle6-3.0.0 xdis-3.6.11

$ pip3 show uncompyle6

Name: uncompyle6

Version: 3.0.0

Summary: Python cross-version byte-code decompiler

Home-page: https://github.com/rocky/python-uncompyle6/

Author: Rocky Bernstein, Hartmut Goebel, John Aycock, and others

Author-email: rb@dustyfeet.com

License: MIT

Location: c:\python36\lib\site-packages

Requires: xdis, spark-parser, six

示例:反编译pyc文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ ls -l

total 4

-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample.cpython-36.opt-1.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample2.cpython-36.opt-1.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ uncompyle6 sample.cpython-36.pyc > s1.py

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ ls -l

total 5

-rw-r--r-- 1 anliven 197121 335 3月 8 00:01 s1.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample.cpython-36.opt-1.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample.cpython-36.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:42 sample2.cpython-36.opt-1.pyc

-rw-r--r-- 1 anliven 197121 122 3月 7 23:41 sample2.cpython-36.pyc

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$ cat s1.py

# uncompyle6 version 3.0.1

# Python bytecode 3.6 (3379)

# Decompiled from: Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)]

# Embedded file name: ./sample.py

# Compiled at: 2018-03-07 22:55:30

# Size of source mod 2**32: 50 bytes

print('Hello Python !')

# okay decompiling sample.cpython-36.pyc

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test/__pycache__

$

示例:反编译pyo文件

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ ls -l

total 8

drwxr-xr-x 1 anliven 197121 0 3月 8 00:01 __pycache__/

-rw-r--r-- 1 anliven 197121 50 3月 7 22:55 sample.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample.pyo

-rw-r--r-- 1 anliven 197121 49 3月 7 23:40 sample2.py

-rw-r--r-- 1 anliven 197121 122 3月 7 23:45 sample2.pyo

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ uncompyle6 sample2.pyo > s2.py

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$ cat s2.py

# uncompyle6 version 3.0.1

# Python bytecode 2.7 (62211)

# Decompiled from: Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)]

# Embedded file name: ./sample2.py

# Compiled at: 2018-03-07 23:40:22

print 'Hello World !'

# okay decompiling sample2.pyo

anliven@DESKTOP-68OFQFP MINGW64 /d/Anliven/Anliven-Code/Test

$

uncompyle6的帮助信息

$ uncompyle6 --help

Usage:

uncompyle6 [OPTIONS]... [ FILE | DIR]...

uncompyle6 [--help | -h | --V | --version]

Examples:

uncompyle6 foo.pyc bar.pyc # decompile foo.pyc, bar.pyc to stdout

uncompyle6 -o . foo.pyc bar.pyc # decompile to ./foo.pyc_dis and ./bar.pyc_dis

uncompyle6 -o /tmp /usr/lib/python1.5 # decompile whole library

Options:

-o output decompiled files to this path:

if multiple input files are decompiled, the common prefix

is stripped from these names and the remainder appended to

uncompyle6 -o /tmp bla/fasel.pyc bla/foo.pyc

-> /tmp/fasel.pyc_dis, /tmp/foo.pyc_dis

uncompyle6 -o /tmp bla/fasel.pyc bar/foo.pyc

-> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis

uncompyle6 -o /tmp /usr/lib/python1.5

-> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis

-c attempts a disassembly after compiling

-d print timestamps

-p use number of processes

-r recurse directories looking for .pyc and .pyo files

--fragments use fragments deparser

--verify compare generated source with input byte-code

--verify-run compile generated source, run it and check exit code

--weak-verify compile generated source

--linemaps generated line number correspondencies between byte-code

and generated source output

--help show this message

Debugging Options:

--asm -a include byte-code (disables --verify)

--grammar -g show matching grammar

--tree -t include syntax tree (disables --verify)

Extensions of generated files:

'.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify)

+ '_unverified' successfully decompile but --verify failed

+ '_failed' decompile failed (contact author for enhancement)

6 - 其他Python反编译工具

Decompyle++

A Python Byte-code Disassembler/Decompiler

https://github.com/zrax/pycdc

Easy Python Decompiler

https://sourceforge.net/projects/easypythondecompiler/

Easy Python Decompiler is python bytecode decompiler, decompiles pyc & pyo files.

python防反编译_Python - 浅谈Python的编译与反编译相关推荐

  1. python中文字符串编码_浅谈python下含中文字符串正则表达式的编码问题

    前言 Python文件默认的编码格式是ascii ,无法识别汉字,因为ascii码中没有中文. 所以py文件中要写中文字符时,一般在开头加 # -*- coding: utf-8 -*- 或者 #co ...

  2. python sys模块作用_浅谈Python中的模块

    模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Mod ...

  3. python 共享内存变量_浅谈python多进程共享变量Value的使用tips

    前言: 在使用tornado的多进程时,需要多个进程共享一个状态变量,于是考虑使用multiprocessing.Value(对于该变量的具体细节请查阅相关资料).在根据网上资料使用Value时,由于 ...

  4. python中怎么计数_浅谈python中统计计数的几种方法和Counter详解

    1) 使用字典dict() 循环遍历出一个可迭代对象中的元素,如果字典没有该元素,那么就让该元素作为字典的键,并将该键赋值为1,如果存在就将该元素对应的值加1. lists = ['a','a','b ...

  5. python数据类型转换原因_浅谈Python数据类型之间的转换

    Python数据类型之间的转换 函数 描述 int(x [,base]) 将x转换为一个整数 long(x [,base] ) 将x转换为一个长整数 float(x) 将x转换到一个浮点数 compl ...

  6. python采用函数编程模式_浅谈Python 函数式编程

    匿名函数lambda表达式 什么是匿名函数? 匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑.lambda 本质上是一个 ...

  7. python打开方式错误_浅谈python 调用open()打开文件时路径出错的原因

    昨晚搞鼓了一下python的open()打开文件 代码如下 def main(): infile =open("C:\Users\Spirit\Desktop\bc.txt",'r ...

  8. python 中arange函数_浅谈Python中range与Numpy中arange的比较

    本文先比较range与arange的异同点,再详细介绍各自的用法,然后列举了几个简单的示例,最后对xrange进行了简单的说明. 1. range与arange的比较 (1)相同点:A.参数的可选性. ...

  9. python方法解析顺序_浅谈Python的方法解析顺序(MRO)

    方法解析顺序, Method Resolution Order 从一段代码开始 考虑下面的情况: class A(object): def foo(self): print('A.foo()') cl ...

最新文章

  1. loss function
  2. 网络-IP/子网掩码/端口
  3. 网络七层协议_IT人计算机网络浅析
  4. oracle crs 0184,ORACLE-RAC启动失败:CRS-0184: Cannot communicate with the CRS daem
  5. 【图像去噪】基于matlab最佳加权双边滤波图像去噪【含Matlab源码 459期】
  6. 神经网络之BP算法(图说神经网络+BP算法理论推导+例子运用+代码)
  7. RegistryWizard(注册表错误修复工具)v3.4.18.528绿色版
  8. 各大高权重搜索引擎博客矩阵链轮?
  9. 淘宝网禁售无证食品和保健品 问题商品将被屏蔽
  10. 『精华』技术大牛养成指南,一篇不鸡汤的成功学实践
  11. R7000P进入ubuntu18.04黑屏问题
  12. 计算机学的痛苦可以换专业,在大学里选错了专业,是一种怎样的“痛苦”体验?...
  13. 德州仪器TI芯片实时监控自动抢购
  14. 解决!只有IE64位浏览器能上网,其他软件都上不了网
  15. 单链表创建学生成绩表 输出学生姓名成绩及班级平均分
  16. 什么是大数据 究竟多大才算是大数据,大数据怎么学习?
  17. 笔记本_cpu_突然性能下降_cpu锁频_cpu降频_重装无用_解锁办法
  18. 精品MySQL面试题
  19. 好用的小工具(二):网站权重查询小工具
  20. 50个超酷photoshop动作演示及下载

热门文章

  1. java自定义sql查询插件,Mybatis插件plugin应用测试,替换查询sql
  2. 解决方法:该站点安全证书的吊销信息不可用。是否继续?
  3. opencv-python之机器视觉
  4. Python基本数据类型之元组
  5. 再温暖的鸡汤不如一场殊死的战争,诸神之战四赛区冠军出炉!
  6. Vue.js下拉框-详细省市联动示例
  7. Maven project deploy to Nexus
  8. 虚拟化--012 多台虚拟机ping不通原因.
  9. 分享下我的博客园CSS
  10. [CLR via C#]17. 委托