当import一个module时,假设我们执行:
执行hello中的语句
pass
sys.modules['mylib'] =mylib
sys.modules['mylib.hello'] =hello
已经该mylib下的所有对象全都加载到sys.modules中。
执行mylib.__init__.py中语句
执行mylib.hello.py中语句(注意该mylib下的其它module不会在执行)
import hello
过程如下:
sys.modules['hello'] =hello
1 搜索sys.modules['hello']是否存在,
if getattr(sys.modules, 'hello') is none:
else:
2 globals()[‘hello'] = hello
每当我们使用一个module时,会从globals()中寻找,如果没有发现就报nameerror。
也就是说一个对象(python万物皆对象)能用,它必须满足: globals()包含该module。
当我们执行:
from mylib import hello
过程如下:
if
getattr(sys.modules, 'mylib.hello') is none:
globals()['hello'] = hello
当一个对象被import时,如果sys.modules中没有该对象值,那么会执行它的所包含的语句以完成初始化。反之就不会执行它的语句。
为什么对象已存在于sys.modules中,却不能用。
因为使用一个对象时,是搜索globals(),如何有就可用。sys.modules只能说明该对象是否加载,不能说明已经在当前环境的全局变量中。
sys.modules可以将对象存放在内存中,加快访问速度。
假如我们的系统中安装同名的包,例如foo。那么我们在import foo时,调用的是哪一个呢?
python解释器按如下顺序进行搜索:
1 搜索sys.path的所有目录,即root package。
2 按照root package下的easy-install.pth的顺序进行搜索。
所以当有多个project包含同名的package时,每次调用的永远都是最先搜索到的,后面的不会被用到。例如,第一个包有foo.foo1,第二包有foo.foo2。那么你只能import foo.foo1,当import foo.foo2时就会出错。
因为出现这种问题,但又想将一个大的package分为多个小的package进行发布、安装时,setuptools中的namespace package就出现了。