python - "import *"究竟导入了什么?

标签 python namespaces python-import

在 Python 中,import * 究竟导入了什么?它会导入包含文件夹中的 __init__.py 吗?

例如,是否需要声明from project.model import __init__,还是from project.model import *就足够了?

最佳答案

from xyz import * 与其他形式的导入相比,其“优势”在于它可以导入所有内容(嗯,几乎... [参见 (a)下面]一切)从当前模块下的指定模块。这允许使用导入模块中的各种对象(变量、类、方法...)无需在它们前面加上模块名称。例如

>>> from math import *
>>>pi
3.141592653589793
>>>sin(pi/2)
>>>1.0

不鼓励这种做法(将 * 导入当前命名空间),因为它

  • 为命名空间冲突提供机会(例如,如果您在导入之前有一个变量名 pi)
  • 如果导入的对象数量很大,可能效率低下
  • 没有明确记录变量/方法/类的来源(很高兴有这个程序的“ self 文档”以供将来访问代码)

因此,通常我们将这种导入 * 实践限制为临时测试等。正如@Denilson-Sá-Maia 所指出的,一些库(例如 pygame)有一个子模块,其中定义了所有最常用的常量和函数,并且这些子模块被有效地设计使用 import * 导入。除了这些特殊的子模块,其他方面最好...:

仅显式导入少数对象

>>>from math import pi
>>>pi
>>>3.141592653589793
>>> sin(pi/2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sin' is not defined

在其自己的命名空间下导入模块(或其别名,特别是如果这是一个长名称,并且程序多次引用其对象)

  >>>import math
  >>>math.pi
  >>>3.141592653589793
  etc..


  >>>import math as m  #bad example math being so short and standard...
  >>>m.pi
  >>>3.141592653589793
  etc..

Python documentation on this topic

(a) 具体来说,使用 from xyz import * 导入什么?
如果 xyz 模块定义了一个 __all__ 变量,它将导入此序列中定义的所有名称,否则将导入所有名称,但以下划线开头的名称除外。

注意许多库都有子模块。例如标准库 urllib 包括子模块,如 urllib.requesturllib.errorsurllib.response等等。一个常见的混淆点是

从 urllib 导入 *

将导入所有这些子模块。 事实并非如此:需要单独显式导入这些文件,例如 from urllib.request import * 等。顺便说一句,这并不特定于 import * ,普通的 import 也不会导入子模块(当然,* 通常是 “everything”的简写 可能会误导人们认为所有子模块和其他所有内容都将被导入)。

关于python - "import *"究竟导入了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2360724/

相关文章:

python - 如何在一张背景图像上移动玩家?

python - 如何将字符串转换为具有相关时区的 python 日期时间对象?

python - 如何向 python 2.6 添加新的编码?

php - Laravel ModelNotFound 异常处理与命名空间

python - 从系列中提取小时/分钟/秒

python - __init__.py imports 还暴露了我使用的模块,而不仅仅是我自己的类

c++ - 你能在 C++ 中转发声明一个命名空间别名吗?

python - 来自其他文件的工作目录中的 execfile

一旦我导入任何 PyQt5 模块,Python.exe 就会停止工作

python - PyCharm:导入错误:没有名为 'websocket' 的模块