marshal.loads函数无法将*.pyc内容加载到代码对象中

5 投票
1 回答
2300 浏览
提问于 2025-04-18 15:58

我在Python 3.3中试了这个

f = open(r'somewhere\my_module.pyc','rb')
contents = f.read()
f.close()

code_obj = marshal.loads(contents[8:])

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: bad marshal data (unknown type code) 

我遇到了错误,所以我把contents这个变量的类型转换成了str

def bytes2str(byte_seq):
    str_seq = ''
    for b in byte_seq:
        str_seq += chr(b)
    return str_seq

contents = bytes2str(contents)
code_obj = marshal.loads(contents[8:])

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

当我在Python 2.7中试这个的时候,我得到了一个代码对象。有什么办法可以解决这个问题,而不使用compile这个内置函数吗?

1 个回答

6

最近版本的Python中,.pyc文件的头部似乎发生了变化,现在是12个字节,而不是之前的8个字节。如果你执行code_obj = marshal.loads(contents[12:]),就能得到你想要的代码对象。

我试着找这个PYC文件格式变化的相关文档,但到现在为止都没有找到。看起来这个变化是从Python 3.3开始的(那时候对导入机制做了很多改动),但我不太确定是哪一部分需要多出来的4个字节。

撰写回答