为什么已经导入模块时需要显式导入模块?

时间:2018-07-26 18:47:24

标签: python sys

每当我在Ubuntu Linux上运行命令时

python3 -v

我得到的详细输出告诉我:

import _frozen_importlib # frozen
import _imp # builtin
import sys # builtin
import '_warnings' # <class '_frozen_importlib.BuiltinImporter'>
import '_thread' # <class '_frozen_importlib.BuiltinImporter'>
import '_weakref' # <class '_frozen_importlib.BuiltinImporter'>
import '_frozen_importlib_external' # <class '_frozen_importlib.FrozenImporter'>
import '_io' # <class '_frozen_importlib.BuiltinImporter'>

还有更多。

但是,我看到导入系统已执行,但是我仍然需要手动导入系统才能使用它。为什么会这样?

1 个答案:

答案 0 :(得分:1)

简短(且不准确)的版本:import foo做两件事:

  • 它从光盘中查找并加载名为“ foo”的模块, if 必要
  • 将模块binds命名为当前名称空间中的名称foo

出于不起作用的相同原因,您必须“手动导入” sys

>>> def r():
...     import random
...     print(random.randint(0, 100))
... 
>>> r()
26
>>> random.randint(10, 20)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'random' is not defined

一种证明导入不是魔术的方法:

$ cat foo.py 
print('foo has been imported')

def fn():
    print('fn has been called')
$ python
>>> import importlib
>>> bar = importlib.__import__('foo')
foo has been imported
>>> bar.fn()
fn has been called

模块名称的工作方式与Python中的其他任何名称相同:

importlib.__import__()创建一个值(在本例中为模块),=将其分配给名称。

使用常规导入,import foo创建一个值(相同的模块)并将其分配给给定的名称(恰好与模块名称相同)。

您可以验证模块仅被加载一次,如下所示:

$ python
>>> import foo
foo has been imported
>>> import foo
>>>

您可以证明一个模块只是另一个值:

>>> import foo
foo has been imported
>>> foo.fn()
fn has been called
>>> bar = foo
>>> bar.fn()
fn has been called