以下分析都是基于以下目录结构:
shebao
libs
mysql_lib.py
redis_lib.py
>>> import libs.redis_lib
>>> dir()['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'redis_lib', 'sys']
在全局sys.modules中形成 libs 本地符号命名空间形成 libs 因此访问CRedis类 需要 使用层级的命名空间引用
>>> import shebao.libs.redis_lib
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'shebao']
import libs 和 import libs.redis_lib
都指挥在当前命名空间形成符号libs (dir())
不同的是 dir(libs) 会不同
在加载libs到当前局部符号空间后 在 import mysql_lib 是可以的因为 dir() 已经多了一个符号A (包的) 搜索路径
from 和 import 的结合使用
>>> from shebao.libs import redis_lib
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'redis_lib']
在全局sys.modules 只有模块shebao
本地符号空间形成 redis_lib
from ..import 和 import 的 都会再sys.modules 中加载 信息 不同之处 是加载完成后 在当前的局部命名空间 是否建立对应符号 from import 会建立且可以控制加载具体的模块对象
import shebao.libs as a
当前局部符号表中会形成符号a 全局模块字典sys.modules 保持不变
总结一下 sys.modules 始终只保存最顶层的模块或者包名 当前局部符号命名空间可能会包含最终引用的类或者模块
import shebao.libs.redis_lib 则 sys.modules(全局模块缓冲中依次存放 shebao shebao.libs shebao.libs.redis_lib)
当前命名空间存放 shebao (package) (底层代码是返回链表头 shebao 存放)
from shebao.libs.reids_lib import CRedis 则
则 sys.modules(全局模块缓冲中依次存放 shebao shebao.libs shebao.libs.redis_lib)
当前命名空间存放 CRedis(package) (顶层代码 是返回链表尾部 CRedis 存储)
import 总是发生在一个包package环境下
在 import libs.mysql_lib 则 当前包环境是libs
在 redis_lib.py中 import mysql_lib 当前的包包环境依然是 libs
最近的一个包环境(非模块)