不同的python模块给出相同的co_code对象
问题描述:
为什么下面两个Python代码模块在编译为pyc格式时具有相同的co_code
属性?不同的python模块给出相同的co_code对象
模块1:
def foo():
response = 'success'
success = 'success' in response
if not success:
raise Exception('failure: %s' % response)
模块2:
def foo():
response = 'success'
success = 'success' in response
if not success:
if 'failure: ' in response:
reason = response[len('failure: '):]
raise Exception('failure: %s' % reason)
else:
raise Exception('neither success nor failure found in response')
如果唯一的区别是,比方说,在字符串中,我可以看到为什么co_code
属性是相同的。但是这两个模块似乎有很大的不同。
这里是我用来执行比较的代码:
import marshal
import sys
def get_pyc_code(path):
'''Extract code object from compiled .pyc file.'''
try:
handle = open(path, 'rb')
except IOError as ex:
print str(ex)
sys.exit()
magic = handle.read(4)
moddate = handle.read(4)
code = marshal.load(handle)
handle.close()
return code
def compare_codes(path1, path2):
'''
Compare the full code objects and co_code attributes of pyc files
path1 and path2.
'''
code1 = get_pyc_code(path1)
code2 = get_pyc_code(path2)
code_same_full = (code1 == code2)
code_same_attr = (code1.co_code == code2.co_code)
if code_same_full and code_same_attr:
print 'pyc files are identical'
else:
print('full code objects the same: %s' % code_same_full)
print('co_code attributes the same: %s' % code_same_attr)
if __name__ == '__main__':
if len(sys.argv) == 3:
compare_codes(sys.argv[1], sys.argv[2])
else:
print('usage: %s foo.pyc bar.pyc' % sys.argv[0])
答
模块级代码对象的代码本身并不代表它里面的函数的代码。你可以看到的代码是什么,如果你使用dis
(我用c1
这里的代码对象):
>>> dis.dis(c1)
1 0 LOAD_CONST 0 (<code object foo at 000000000234D230, file "m1", line 1>)
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (foo)
9 LOAD_CONST 1 (None)
12 RETURN_VALUE
你可以看到,该模块的代码上是相同的,因为这两个模块做什么,但定义单一功能。 函数的代码是不同的,但这不是你在这里看到的。
比较代码对象而不是仅仅'co_code'属性足以识别不同的模块吗? –
@JohnGordon:我不知道。它似乎工作,但我真的不知道如何定义代码对象上的等式比较。你想在这里完成什么? – BrenBarn
我正在开发一个作为编译好的pyc文件打包在RPM中的软件应用程序。我试图想出一种方法来比较两个这样的RPM文件来识别两者之间的任何变化。 –