import vs __import __()vs importlib.import_module()?

tem*_*ame 35 python python-import

我注意到Flask正在使用Werkzeug来__import__模块,我有点困惑.我去检查过了它的文档,发现它似乎以某种方式给你的地方查找模块方面更多的控制,但我不知道究竟怎么和为零的想法它是如何从不同的importlib.import_module.

Werkzeug示例中的奇怪之处在于它只是说__import__(import_name),所以我看不出与使用该import语句有什么不同,因为它忽略了可选的额外参数.

谁能解释一下?我看了之前在SO上提出类似问题的其他人,但他们的问题并不是很清楚,答案根本没有解决这个问题.

Mar*_*ers 49

__import__是一个用于导入模块的低级钩子函数; 它可以用来动态导入模块,方法是将模块名称作为变量导入,import语句不允许这样做.

importlib.import_module()是钩子*的包装器,为函数生成一个很好的API; 它是Python 2的最新成员,并且在Python 3中更加充实.__import__通常使用的代码库因为它们希望与旧版Python 2保持兼容,例如Python 2.7之前的任何版本.

使用的一个副作用__import__可能是它返回导入的模块并且不向命名空间添加任何内容; 您可以使用它导入,而不必删除新名称,如果您不想要新名称; using import somename将添加somename到您的命名空间,__import__('somename')而是返回导入的模块,然后您可以忽略它.Werkzeug因为这个原因在一个地方使用了钩子.

所有其他用途都与动态导入有关.Werkzeug支持Python 2.6仍然无法使用importlib.


* importlib是一个Pure-Python实现,import_module()并将使用该实现,惠斯特__import__将使用C优化版本.两个版本都回调,importlib._bootstrap._find_and_load()所以差异主要是学术上的.

  • @Aerovistae:更新了一点;`import sys` 将名称 `sys` 添加到您的命名空间(绑定到模块),`__import__('sys')` 将 `sys` 模块对象返回给调用者,然后调用者可以自由地忽略该对象。 (2认同)
  • @Mahesha999:要从存储在字符串中的源代码动态生成模块,您根本不需要查看`__import__`。使用 `module = imporlib.util.module_from_spec(importlib.machinery.ModuleSpec(module_name, None, origin='<string>'))` 创建一个空模块实例,使用 `sys.modules[module_name] = module` 存储模块,然后使用 exec(sourcecode, module.__dict__)` 来执行源代码。并且永远不要执行用户提供的代码,这是极其不安全的。 (2认同)

7st*_*tud 7

__import__(import_name),所以我看不出这与仅使用 import 语句有何不同

无论__import__()和importlib.import_module()让你当你有模块名作为一个字符串导入模块。你不能写:

x = 're'
import x
Run Code Online (Sandbox Code Playgroud)

否则你会得到:

 File "1.py", line 3, in <module>
 import x ImportError: No module named x
Run Code Online (Sandbox Code Playgroud)