本文探讨一下pyhton中可执行/调用的对象有哪些?
大家首先想到的是函数/方法,但除了函数/方法之外,还有其他的对象是可执行/调用的,大家都了解吗?任何一个可执行对象都有一个code object,它是一个字节码序列,python虚拟机解释执行的就是字节码。
可执行的对象除了函数/方法之外,还有模块(module)、类(class)、生成器、协程、异步生成器。
既然可执行对象都有一个code object,那它在哪呢?本文将揭开它们的面纱。
先看模块,大家都知道执行一个模块或者导入一个模块,都要执行那个模块,那它的code object在哪?稍微有点经验的pythoner都知道python解释器在执行模块前,先要编译模块生成一个pyc文件,模块的code object就在pyc文件中,先看pyc文件的格式
Magic Number、Bit Field、Last Modified Time、File Size这四个字段各占4个字节,构成了pyc文件的Header,接下来的便是module的code object了。
下面给出一个解析pyc文件的函数:
import sys, time, struct, dis
def parse(pyc):
with open(pyc, "rb") as fp:
#resolve header
magic = struct.unpack("<l", fp.read(4))[0]
bitfield = fp.read(4)
modtime = time.asctime(time.localtime(struct.unpack("<l", fp.read(4))[0]))
filesize = struct.unpack("<L", fp.read(4))[0]
print("magic: ", magic, "bit field: ", bitfield, "modified time: ", modtime, "file size: ", filesize)
#resolve code object
code = fp.read()
dis.dis(code)
if __name__ == '__main__':
parse(sys.argv[1])
执行时候把pyc文件的路径名传入,便可以查看pyc文件的Header和它code object的字节码了。如果你的python源文件没有生成对应的pyc文件,可以执行python -m compileall xx.py来生成。
再来看类的code object在哪。直接上代码:
import dis
cls = '''
class x:
def __init__(self):pass
def f(self):pass
...
dis.dis(cls)
看执行结果:
看类x的code object里的字节码,它的逻辑也就是把类的__module__、__qualname__、__init__、f等属性对象装入到一个namespace中,可见执行一个类,生成一个类对象,它首先就是在做一个打包工作,把类体里面定义的各个对象打包到一个字典里面,了解元编程的朋友知道,后续python解释器会把它作为参数传入元类的构造函数里,元类调用之后返回的就是生成的类对象。
函数、生成器和异步生成器的code object对象在函数/生成器函数/异步生成器函数的__code__.co_code属性中,不再赘述。
标签:__,执行,code,哪些,python,object,生成器,调用,pyc From: https://blog.csdn.net/weixin_40756114/article/details/137341300