type(os)-->,os本身的类别为模块,type(os.path)-->,os.path也为模块,说明python可以通过'模块.模块'的格式来引用模块。
以os.path为例,来说明一下这种结构的机制。
1.import module是可以将被引用模块中的所有对象以及__all__列表中所有对象加载到当前模块中来
2.from module import * 是根据__all__列表来加载模块,如果没有定义__all__列表,则以‘_’开头的对象是不会被引用的。
os模块初始化时__all__列表:
__all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
"defpath", "name", "path", "devnull",
"SEEK_SET", "SEEK_CUR", "SEEK_END"]
当执行 import os时,以linux环境为场景:
if 'posix' in _names:
name = 'posix'
linesep = '
'
from posix import *
try:
from posix import _exit
except ImportError:
pass
import posixpath as path
import posix
__all__.extend(_get_exports_list(posix))
del posix
‘import posixpath as path’ ,可以看出os.path模块对应的实际模块名称为posixpath ,那么python解释器如何通过os.path找到实际模块呢?sys.modules['os.path'] = path,这句将os.path对应模块添加到sys.modules字典中。 __all__.extend(_get_exports_list(posix))将posix中所有的对象都添加到os当前的__all__列表中,os模块对应的py文件中有renames方法,没有rename方法,为什么可以使用os.rename呢?就是posix模块中rename方法被添加到os的模块列表中了。可以通过dir(posix)发现posix模块中确实有rename方法。