2015-10-20 109 views
0

为什么下面两个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]) 

回答

1

模块级代码对象的代码本身并不代表它里面的函数的代码。你可以看到的代码是什么,如果你使用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 

你可以看到,该模块的代码上是相同的,因为这两个模块做什么,但定义单一功能。 函数的代码是不同的,但这不是你在这里看到的。

+0

比较代码对象而不是仅仅'co_code'属性足以识别不同的模块吗? –

+0

@JohnGordon:我不知道。它似乎工作,但我真的不知道如何定义代码对象上的等式比较。你想在这里完成什么? – BrenBarn

+0

我正在开发一个作为编译好的pyc文件打包在RPM中的软件应用程序。我试图想出一种方法来比较两个这样的RPM文件来识别两者之间的任何变化。 –

相关问题