python是谁维护的_Python模块维护

模块

在Python中,一个.py文件,就是一个模块。

CPython虚拟机自己模拟了进程和线程的概念。在Cpython初始化运行环境的时候,会创建一个空的进程,进而在进程中创建一个空的线程。CPython对模块维护的策略是:

Python中所有的模块都被维护在进程中,而所有的线程共享进程中的模块资源。

CPython用一个结构体PyInterpreterState来表示虚拟进程,这里只列出比较重要的几行,若要查看完整代码,请参阅CPython源码中的Include/pystate.h文件:

modules:维护了进程中所有的modules(包括内建和用户自定义模块),维护在一个字典中。

sysdict:我们最熟悉的sys内置模块,维护在一个字典中。

builtins:builtins内置模块,维护在一个字典中。

它们三者之间的关系,可以用如下图来描述(点击查看大图:模块维护图):

默认情况下,CPython只会将builtins模块添加到名字空间中,就是__builtins__。我们无法直接访问modules,但是从图中可以看出,sys中维护了一个字段,叫modules,该字段正好指向了modules:

从sys.modules.keys()可以看到进程中维护的所有模块,比如,__main__模块,sys模块(由此可见,modules中也维护了一个字段,该字段指向了sys,sys模块和modules模块互指)。

CPython中的模块是维护在一个PyModuleObject结构体中的,该结构体的md_dict指向一个字典,该字典中维护了该模块下的所有符号。当然,CPython还会在md_dict中添加两个字段:__name__和__doc__,分别用来表示该模块的名字和文档说明:

builtins模块

在Python2中,builtins模块叫__builtin__(不加s)。以下叙述,我们使用builtins。

不论是在交互式命令行中,还是在文件中,我们都可以直接使用一些函数,比如dir()。当输入dir()的时候,Python会在名字空间中寻找dir这个符号,Python的名字空间分为:

locals名字空间

globals名字空间

builtin名字空间

Python会沿着locals->globals->builtin路径寻找符号。使用__builtins__.__dict__.keys()就可以看到builtin名字空间中维护的符号。

最后,在builtin名字空间中找到了符号dir。当然,我还可以重定义dir函数,这样在locals名字空间中,就会维护一个符号dir,因为Python会沿着locals->globals->builtin路径进行寻找,所以,最先在locals中找到dir,调用用户自定义函数:

那么,到底什么是builtins模块呢?我们需要深入去探讨一下。CPython在创建完进程和线程后,所做的第一步事情就是创建builtins模块,所做的操作就是将所有的内建函数添加到该模块中,最后,将builtins模块中的__name__赋值为builtins。我们可以在sys.modules中看到这个模块:

默认情况,builtins模块并没有被加载到globals名字空间中。但是,Python定义了一个魔术属性__builtins__来访问该模块。我想这么做是为了保持模块操作的一致性。

最后,需要注意的是,当模块不被当做主模块的时候,其globals名字空间中的__builtins__不再指向builtins模块,而是指向了builtins模块的md_dict。

小结:

__builtin__在Python3中被更名为builtins,该模块被维护在进程结构体的modules中;

__builtins__作为一个魔法属性,可以访问到内建builtins模块;

若是在主模块中,__builtins__和__builtin__(builtins)都指向同一个内建模块;若是被import的module,其__builtins__则等价于__builtin__.__dict__(builtins.__dict)。原因不详;

__main__模块

在Python中,当前运行的模块,被叫做主模块。

__main__模块是指向自身的模块,默认情况下,该module也未被import。但是,我们可以通过sys.modules访问到它:

当然,我们也可以将其import:

由此可见,__name__和__main__.__name__就是指向的同一个字符串。因为主模块的名字属性被改为了'__main__',所以,如果我们想知道主模块的文件名字,可以使用如下方法:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值