sys.modules和__import__
>>> import sys
# 这个时候os这个module已经被加载了,但是在当前作用域并不可见。 >>> sys.modules['os'] <module 'os' from '/usr/lib/python2.7/os.pyc'> >>>
# 访问os会被提示NameError >>> os Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'os' is not defined >>>
# 将os模块导入到当前作用域 >>> import os >>> os <module 'os' from '/usr/lib/python2.7/os.pyc'> >>>
# 从当前作用域删除os >>> del os >>>
# 但是os模块还存在sys.modules中 >>> sys.modules['os'] <module 'os' from '/usr/lib/python2.7/os.pyc'> >>>
# 此时再访问os模块就会报错 >>> os Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'os' is not defined
sys.modules.keys()中的每个模块确实在python启动的时候被导入了,但是它们不像__builtins__那样直接暴露出来了,它们还隐藏着,需要import把它们加入进来。
再比如,module A引用了module B,当import了module A,实际上module B也被间接加载了,但肯定是看不到的。
###########################################################################################################
__import__(name[, globals[, locals[, fromlist[, level]]]])
Note
This is an advanced function that is not needed in everyday Python programming, unlike importlib.import_module().
这是一个高级功能,在日常的python编程中并不常用,不像importlib.import_module()。
This function is invoked by the import statement. It can be replaced (by importing the __builtin__ module and assigning to__builtin__.__import__) in order to change semantics of the import statement, but nowadays it is usually simpler to use import hooks (see PEP 302). Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.
这个函数被import语句调用。如果改变import语句的语义(通过导入__builtin__并且使用__builtin__.__import__) 则可以可以代替__import__。
直接使用__import__是非常少见的,除了你需要在运行时刻才知道需要导入的模块名。
The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The fromlist gives the names of objects or submodules that should be imported from the module given by name. The standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.
这个函数导入模块名name,默认情况下使用globals和locals去决定如何在包的上下文中解释模块的name。
fromlist指定了需要在模块name中导入的子模块或者对象。
标准的实现没有使用locals,但是只使用了globals去检测import语句的包的上下文关系。
level specifies whether to use absolute or relative imports. The default is -1 which indicates both absolute and relative imports will be attempted. 0 means only perform absolute imports. Positive values for level indicate the number of parent directories to search relative to the directory of the module calling __import__().
level参数指定了是使用相对导入还是绝对导入。默认的是-1,说明绝对和相对导入都会去尝试。
0的意思是只做绝对导入。
如果level是正整数,则指明了调用__import__的模块需要搜索的父目录的相对路径的数量
When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned.
当name参数是package.module格式时,顶层的包(第一个点号之前的)会被返回,而不是完整的name名称。
无论如何,当存在fromlist参数时,模块名为name的会被返回。
For example, the statement import spam results in bytecode resembling the following code:
举例,import spam的结果和下面的代码类似:
spam = __import__('spam', globals(), locals(), [], -1)
The statement import spam.ham results in this call:
import spam.ham语句的结果如下:
spam = __import__('spam.ham', globals(), locals(), [], -1)
Note how __import__() returns the toplevel module here because this is the object that is bound to a name by the import statement.
On the other hand, the statement from spam.ham import eggs, sausage as saus results in
从其他方面来说,语句from spam.ham import egges, sausage as saus的结果是:
_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1) eggs = _temp.eggs saus = _temp.sausage
Here, the spam.ham module is returned from __import__(). From this object, the names to import are retrieved and assigned to their respective names.
If you simply want to import a module (potentially within a package) by name, use importlib.import_module().
Changed in version 2.5: The level parameter was added.
Changed in version 2.5: Keyword support for parameters was added.
举例来说:
>>> t = __import__('django.http', fromlist=['Cookie']) >>> t <module 'django.http' from '/usr/local/lib/python2.7/dist-packages/django/http/__init__.pyc'> >>> t.Cookie <module 'Cookie' from '/usr/lib/python2.7/Cookie.pyc'>
而这样只返回了顶层的django包:
>>> t = __import__('django.http') >>> t <module 'django' from '/usr/local/lib/python2.7/dist-packages/django/__init__.pyc'>