比较两个 python 文件是否产生相同的字节码(代码是否相同)
compare whether two python files result in same byte code (are code wise identical)
我们正在进行一些代码清理。
清理只是关于格式化(如果有问题,那么我们甚至可以假设,行号不会改变,但理想情况下我也想忽略行号的变化)
为了确保没有意外的代码更改,我想找到一种简单/快速的方法来比较两个源代码。
所以让我们假设,我有 file1.py
和 file2.py
有效的是使用
py_compile.compile(filename)
创建 .pyc 文件然后使用
uncompyle6 pycfile
,然后去掉注释比较结果,
但这太过分了而且非常慢。
我想象的另一种方法是复制
file1.py
例如 file.py
,
使用 py_compile.compile("file.py")
并保存 .pyc 文件
然后复制 file2.py
例如到 file.py
并使用
使用 py_compile.compile("file.py")
并保存 .pyc 文件
最后比较两个生成的 .pyc 文件
这是否适用于所有(当前)版本 >= python 3.6
如果我至少记得 python2,pyc 文件可能包含时间戳或绝对路径,这可能会使比较失败。 (至少如果 pyc 文件的生成是 运行 在两台不同的机器上)
有没有一种干净的方法来比较py2文件的字节码?
作为奖励功能(如果可能的话)我想为每个字节码创建一个哈希,我可以存储它以供将来参考。
可能不是想要的答案 - 但您为什么不使用 diff 工具来比较文件是否已更改?
https://linuxhandbook.com/diff-command/
如果文件被更改,请使用像 meld 这样的合并工具来比较更改 http://meldmerge.org/
您可以尝试使用 Python 的内部 compile
function,它可以从字符串编译(在您的情况下从文件中读入)。例如,编译和比较来自两个等效程序和一个几乎等效程序的结果代码对象,然后仅出于演示目的(您 不想做的事情)执行一些代码对象:
import hashlib
import marshal
def compute_hash(code):
code_bytes = marshal.dumps(code)
code_hash = hashlib.sha1(code_bytes).hexdigest()
return code_hash
source1 = """x = 3
y = 4
z = x * y
print(z)
"""
source2 = "x=3;y=4;z=x*y;print(z)"
source3 = "a=3;y=4;z=a*y;print(z)"
obj1 = compile(source=source1, filename='<string>', mode='exec', dont_inherit=1)
obj2 = compile(source=source2, filename='<string>', mode='exec', dont_inherit=1)
obj3 = compile(source=source3, filename='<string>', mode='exec', dont_inherit=1)
print(obj1 == obj2)
print(obj1 == obj3)
exec(obj1)
exec(obj3)
print(compute_hash(obj1))
打印:
True
False
12
12
48632a1b64357e9d09d19e765d3dc6863ee67ab9
这将使您免于复制 py 文件、创建 pyc 文件、比较 pyc 文件等操作
注:
如果您需要可重复的散列函数,即 returns 在连续的程序运行中计算相同的代码对象时,compute_hash
函数会重复使用相同的值。
我们正在进行一些代码清理。 清理只是关于格式化(如果有问题,那么我们甚至可以假设,行号不会改变,但理想情况下我也想忽略行号的变化)
为了确保没有意外的代码更改,我想找到一种简单/快速的方法来比较两个源代码。
所以让我们假设,我有 file1.py
和 file2.py
有效的是使用
py_compile.compile(filename)
创建 .pyc 文件然后使用
uncompyle6 pycfile
,然后去掉注释比较结果,
但这太过分了而且非常慢。
我想象的另一种方法是复制
file1.py
例如 file.py
,
使用 py_compile.compile("file.py")
并保存 .pyc 文件
然后复制 file2.py
例如到 file.py
并使用
使用 py_compile.compile("file.py")
并保存 .pyc 文件
最后比较两个生成的 .pyc 文件
这是否适用于所有(当前)版本 >= python 3.6
如果我至少记得 python2,pyc 文件可能包含时间戳或绝对路径,这可能会使比较失败。 (至少如果 pyc 文件的生成是 运行 在两台不同的机器上)
有没有一种干净的方法来比较py2文件的字节码?
作为奖励功能(如果可能的话)我想为每个字节码创建一个哈希,我可以存储它以供将来参考。
可能不是想要的答案 - 但您为什么不使用 diff 工具来比较文件是否已更改? https://linuxhandbook.com/diff-command/
如果文件被更改,请使用像 meld 这样的合并工具来比较更改 http://meldmerge.org/
您可以尝试使用 Python 的内部 compile
function,它可以从字符串编译(在您的情况下从文件中读入)。例如,编译和比较来自两个等效程序和一个几乎等效程序的结果代码对象,然后仅出于演示目的(您 不想做的事情)执行一些代码对象:
import hashlib
import marshal
def compute_hash(code):
code_bytes = marshal.dumps(code)
code_hash = hashlib.sha1(code_bytes).hexdigest()
return code_hash
source1 = """x = 3
y = 4
z = x * y
print(z)
"""
source2 = "x=3;y=4;z=x*y;print(z)"
source3 = "a=3;y=4;z=a*y;print(z)"
obj1 = compile(source=source1, filename='<string>', mode='exec', dont_inherit=1)
obj2 = compile(source=source2, filename='<string>', mode='exec', dont_inherit=1)
obj3 = compile(source=source3, filename='<string>', mode='exec', dont_inherit=1)
print(obj1 == obj2)
print(obj1 == obj3)
exec(obj1)
exec(obj3)
print(compute_hash(obj1))
打印:
True
False
12
12
48632a1b64357e9d09d19e765d3dc6863ee67ab9
这将使您免于复制 py 文件、创建 pyc 文件、比较 pyc 文件等操作
注:
如果您需要可重复的散列函数,即 returns 在连续的程序运行中计算相同的代码对象时,compute_hash
函数会重复使用相同的值。