Python的运行机制--pyc文件格式浅析

Python的原始代码在运行前都会被先编译成字节码,并把编译的结果保存到一个一个的PyCodeObject中,pyc 文件即是把PyCodeObject从内存中以marshal格式保存到文件后的结果。


下面我们来通过测试和工具来了解下pyc文件到底有些什么东西。


先写个简单的测试程序:

test.py

import dis
myglobal = True

def add(a):
    b = 1
    a += b
    return a

class world:
    def __init__(self):
        pass
    def sayHello(self):
        print 'hello,world'

w = world()
w.sayHello()



在这个例子里,全局变量,函数,类都有了,然后我们用下面的命令把它编译成pyc文件:

python -m compileall test.py


然后我们通过下面的代码分析一下test.pyc:

showfile.py

import dis, marshal, struct, sys, time, types

def show_file(fname):
    f = open(fname, "rb")
    magic = f.read(4)
    moddate = f.read(4)
    modtime = time.asctime(time.localtime(struct.unpack('L', moddate)[0]))
    print "magic %s" % (magic.encode('hex'))
    print "moddate %s (%s)" % (moddate.encode('hex'), modtime)
    code = marshal.load(f)
    show_code(code)
     
def show_code(code, indent=''):
    old_indent = indent
    print "%s<code>" % indent
    indent += '   '
    print "%s<argcount> %d </argcount>" % (indent, code.co_argcount)
    print "%s<nlocals> %d</nlocals>" % (indent, code.co_nlocals)
    print "%s<stacksize> %d</stacksize>" % (indent, code.co_stacksize)
    print "%s<flags> %04x</flags>" % (indent, code.co_flags)
    show_hex("code", code.co_code, indent=indent)
    print "%s<dis>" % indent
    dis.disassemble(code)
    print "%s</dis>" % indent

    print "%s<names> %r</names>" % (indent, code.co_names)
    print "%s<varnames> %r</varnames>" % (indent, code.co_varnames)
    print "%s<freevars> %r</freevars>" % (indent, code.co_freevars)
    print "%s<cellvars> %r</cellvars>" % (indent, code.co_cellvars)
    print "%s<filename> %r</filename>" % (indent, code.co_filename)
    print "%s<name> %r</name>" % (indent, code.co_name)
    print "%s<firstlineno> %d</firstlineno>" % (indent, code.co_firstlineno)

    print "%s<consts>" % indent
    for const in code.co_consts:
        if type(const) == types.CodeType:
            show_code(const, indent+'   ')
        else:
            print "   %s%r" % (indent, const)
    print "%s</consts>" %
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值