在讲加载之前,要讲一个sys模块的modules用法的意义:
import sys
print(sys.modules)
sys.modules返回的是一个字典,里面包含着当前系统运行之前预加载的一些基础模块,key是名字,value是指向模块实际存放的位置。
os和os.path的区别:
import os
import os.path
一,import os时,就会去找sys.modules当前系统是否已经加载,如果已经加载就不会再次导入模块了
二,import os.path:我们知道Python中import后面必须是一个模块名,但是这里os.path你在Python的模块目录中是找不到这个叫path.py这个名字的文件。
Python3.6.4 os模块的一段源码:
_names = sys.builtin_module_names
# Note: more names are added to __all__ later.
__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
"defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
"SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
"popen", "extsep"]
def _exists(name):
return name in globals()
def _get_exports_list(module):
try:
return list(module.__all__)
except AttributeError:
return [n for n in dir(module) if n[0] != '_']
# Any new dependencies of the os module and/or changes in path separator
# requires updating importlib as well.
if 'posix' in _names:
name = 'posix'
linesep = '\n'
from posix import *
try:
from posix import _exit
__all__.append('_exit')
except ImportError:
pass
import posixpath as path
try:
from posix import _have_functions
except ImportError:
pass
import posix
__all__.extend(_get_exports_list(posix))
del posix
elif 'nt' in _names:
name = 'nt'
linesep = '\r\n'
from nt import *
try:
from nt import _exit
__all__.append('_exit')
except ImportError:
pass
import ntpath as path
import nt
__all__.extend(_get_exports_list(nt))
del nt
try:
from nt import _have_functions
except ImportError:
pass
else:
raise ImportError('no os specific module found')
sys.modules['os.path'] = path
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
devnull)
del _names
从这段源码中分析我们可以得出为什么有path这个模块!
一,在启动Python解释器时,Python会预先装在一些基本的模块,如os、sys等;在装载os模块时,程序也是从模块的开始一直读取运行到文件的结尾。
1,在开始时,程序把当前sys.builtin_module_names系统的一些信息收集起来返回一个元组,并打一个标签叫_names;
2,接下来通过if语句判断当前操作系统遵循什么标准开发的,如linux是Posix,Windows是NT;
3,根据判断加载相应的模块并as给一个新的名字path;到这里我们就拿到path,path只是对应加载模块的别名
4,到这里为止,我们并不能通过os模块中提供的all中的path来直接 import os.path
import posixpath as path
import ntpath as path
总结:
os和os.path两个模块在解释器运行之前已经加载,这些只是相当于名称,通过字典类型,指向真正的模块位置。
os和os.path的关联:
问题:如果说path不是os的子模块,为什么我们能通过from os.path import exists?
1,在解释器运行之前会预先加载一些必要的模块,如os,再通过源码来理解。
2,加载os的判断当前系统是什么标准的,并加载真正的模块并as命名path
3,接下来看os源码中的这段代码
sys.modules['os.path'] = path
sys.modules:指的是当前解释器运行中加载的模块,以字典类型表示。
这段代码什么意思?
总结: