为什么我需要在模块已经导入时显式导入它们?

Why do i need to explicitly import modules when they're already imported?

每当我 运行 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'>

还有更多。

但是看到执行了import sys,但还是需要手动import sys才能使用。为什么会这样?

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

  • 它从光盘中查找并加载名为 "foo" 的模块,if necessary
  • binds模块到当前名称空间foo中的名称

你必须 "manually import" 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

证明 import 没什么神奇的方法:

$ 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