不同的python模块提供相同的co_code对象

时间:2015-10-20 18:21:33

标签: python

为什么以下两个Python代码模块在编译为pyc格式时具有相同的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 个答案:

答案 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   

您可以看到两者的模块代码相同,因为两个模块除了定义单个函数外什么都不做。 功能的代码不同,但这不是您在此处查看的内容。