在 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.request
、urllib.errors
、urllib.response
等等。一个常见的混淆点是
从 urllib 导入 *
将导入所有这些子模块。 事实并非如此:需要单独显式导入这些文件,例如 from urllib.request import *
等。顺便说一句,这并不特定于 import *
,普通的 import
也不会导入子模块(当然,*
通常是 “everything”的简写 可能会误导人们认为所有子模块和其他所有内容都将被导入)。
关于python - "import *"究竟导入了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2360724/