Module & Package

module是一个Python文件,而package是一个目录结构。package中必须包含__init__.py, 该文件可以为空,主要作用是让python识别这个目录为package。

__init__.py中可以使用__all__这个列表来指定在from this_module import *时时,哪些模块会被自动载入

__all__ = [ 'test' ] module的字符串名

__init__.py会在import该package或者该package中的Module之前被执行,并且只执行一次。

当import package时,将会只执行该__init__.py,我们可以指定需要载入的子module。这样在载入该包后,这些module就可用了。

当from package import *时,__all__定义的是需要导入的模块

当from module import *时,__all__定义的是导入的名称

Module Hierachy

我们知道os是一个module,而path是os的sub module,他们不是以package的形式来组织的。如果我们要以module,submodule的形式来组织层级结构,比如os.path,那么我们该怎么做?

当我们import os.path时,其实python是这么来载入的这些module的

importing_process
    1. search sys.modules
    2. find a finder
        call finder.find_modules(fullname), if found, return a loader
    3. call loader.load_modules(fullname)
    4. add to sys.modules

importing os (fullname = os)
importing path (fullname = os.path)

因为module name中出现了dot,所以python会对每个identifier进行分别处理,他会现在sys.modules中找os,如果找到,ok,继续import path。在准备import path时,实际使用的是os.path这个fullname,而不是简单的identifier。假设os.path还没有载入(在sys.modules中没有找到),那么他会查找能够找到path的finder,如果这个finder能够找到os.path,那么返回一个loader,该loader会被调用,来载入module,如果失败,则抛出ImportError异常。

由于os、path都是module,所以如果不做特殊处理,Python会报

Traceback (most recent call last):
 File "", line 1, in <module>
ImportError: No module named path 
查看os中的代码可以知道,os在import path后,将其添加到sys.modules中,
# os.py
import path # persudo code
sys.modules['os.path'] = path 

这样,当第二次python试图导入path时,将会直接在sys.modules中找到os.path,从而避免了ImportError。

我们要做的就是,在导入第一个parent module时,手动导入submodule,并且将submodule添加到sys.modules中。submodule必须由parent module预先添加到sys.modules中,一方面是为了防止ImportError,另一方面是为了submodule还能够被部分独立地重用。

考虑我们有3个module,分别是a, b, c,前一个是后一个Parent。所以可以这么实现,

# a.py
import b
import sys
sys.modules['a.b'] = b
sys.modules['a.b.c'] = b.c

# b.py
import c
import sys
sys.modules['b.c'] = c 
优点:简单,不用以目录形式组织module hierachy 

缺点:复杂,需要手动将submodule加入到sys.modules

Package Hierachy

TODO:

Reference:

    [1] Python 2.7 documentation - keyword sys.modules

    [2] New Import Hooks - Specification part 1: The Importer Protocol

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值