Python 当模块';你已经进口了吗?

Python 当模块';你已经进口了吗?,python,sys,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.B

每当我在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 _freezed _importlib#freezed
导入内置
导入系统内置
导入“_警告”#
导入“_线程”#
输入“weakref”
导入“\u冻结\u导入lib\u外部”\
导入“_io”#
还有更多

然而,我看到import sys已经执行,但是我仍然需要手动导入sys来使用它。为什么会发生这种情况?

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

  • 如有必要,它将查找并从名为“foo”的模块加载光盘
  • 在当前名称空间中将模块命名为
    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
模块名称与Python中的任何其他名称类似:

importlib.\uuuu import\uuuu()
创建一个值(本例中为模块),然后
=
将其分配给名称

对于常规导入,
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

import
是每个命名空间的。将某些内容导入到一个模块的命名空间中会将其存储在缓存中,但如果没有明确的请求,则无法使其他模块使用它——如果这不是真的,您将永远不知道哪些名称在命名空间中,哪些名称不在命名空间中,因为它们可能是由系统上的随机其他代码导入的
importlib.\uuuu import\uuuu
是一种矛盾修饰法。使用
importlib.import\u module
@wim:我不认为这个词的意思是你认为它的意思……无论如何,是的,
\uuu import\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。import语句使用
内置项。您可以通过
import importlib向自己证明这一点;del importlib.\uuuu import\uuuu
然后导入任何模块-它仍然可以工作。删除内置的
。\u\u导入\u
,它将停止工作。我知道矛盾修饰法的含义,使用
importlib
的全部目的是提供一个公共API,这样您就不会使用
\uuuuuuu import\uuuuu
。我放弃,您赢了
>>> import foo
foo has been imported
>>> foo.fn()
fn has been called
>>> bar = foo
>>> bar.fn()
fn has been called