建议不要import *
在Python中使用。
任何人都可以分享原因,以便下次可以避免吗?
import *
不适用于Python 2或3的我
建议不要import *
在Python中使用。
任何人都可以分享原因,以便下次可以避免吗?
import *
不适用于Python 2或3的我
Answers:
因为它在名称空间中放入了很多东西(可能会遮盖以前导入的其他对象,所以您将一无所知)。
因为您不完全知道要导入的内容,而且不容易找到从哪个模块导入的内容(可读性)。
因为您不能使用像pyflakes
静态检测代码中的错误之类的出色工具。
numpy.any
阴影遮住了any
,from numpy import *
或者“帮助”工具为他们做了阴影。
import *
使订单中的import
显著报表......即使是通常不关心进口秩序标准库模块。import
当以前的进口战争中的伤亡者成为唯一幸存者时,像按字母顺序排列的陈述那样无辜的行为可能会破坏您的脚本。(即使您的脚本现在可以正常工作并且永远不会更改,如果导入的模块引入了一个新名称来替换您所依赖的名称,它可能会在以后的某个时间突然失败。)
use strict
(JavaScript var
)的原因。顺便说一句,Python当然不是无类型的(实际上是强类型的)。无论如何,即使如果你是正确的,这将仍然矛盾的Python的禅,引用这个答案。
您不传递**locals()
给函数,是吗?
因为Python缺少“包括”语句,并且该self
参数是明确的,而且范围规则相当简单,它通常很容易在一个变量指向一个手指,告诉哪里该对象来自-没有阅读其他模块,无任何IDE(由于语言是非常动态的,因此反省自省的方式)。
该import *
休息了这一切。
而且,它有隐藏错误的具体可能性。
import os, sys, foo, sqlalchemy, mystuff
from bar import *
现在,如果bar模块具有“ os
”,“ mystuff
”等属性中的任何一个,它们将覆盖显式导入的属性,并可能指向非常不同的事物。__all__
在bar中定义通常是很明智的-这说明了要隐式导入的内容-但是,如果不读取和解析bar模块并跟随其导入,仍然很难跟踪对象的来源。import *
获得项目所有权时,首先要解决的网络问题。
不要误会我:如果import *
丢失了,我会哭着拥有它。但是必须谨慎使用。一个好的用例是在另一个模块上提供Facade接口。同样,使用条件导入语句或在函数/类名称空间中进行导入也需要一些纪律。
我认为在大中型项目或具有多个贡献者的小型项目中,就静态分析而言,至少需要保持卫生(至少运行pyflakes甚至更好地配置正确的pylint)才能捕获多种错误。他们发生了。
当然,由于这是python-可以随意打破规则并进行探索-但要警惕可能增长十倍的项目,如果源代码缺少规范,那将是一个问题。
execfile()
。幸运的是,它很少在3.x中使用和使用。
**vars()
如果被调用函数在另一个文件中,如何包含全局变量?:P
http://docs.python.org/tutorial/modules.html
请注意,通常不赞成
*
从模块或包进行导入的做法,因为这通常会导致可读性差的代码。
这些都是很好的答案。我要补充一点,当教新人们使用Python进行编码时,处理import *
非常困难。即使您或他们没有编写代码,它仍然是绊脚石。
我教孩子们(大约8岁)用Python编程来操纵Minecraft。我喜欢给他们一个有用的编码环境,以供他们使用(Atom Editor)并教授REPL驱动的开发(通过bpython)。在Atom中,我发现提示/完成与bpython一样有效。幸运的是,与其他一些统计分析工具不同,Atom并不受它的欺骗import *
。
但是,让我们举个例子...在这个包装器中,他们from local_module import *
是一堆模块,其中包括这个块列表。让我们忽略名称空间冲突的风险。通过这样做,您from mcpi.block import *
就可以使晦涩难懂的块的整个列表成为必需的东西,以便您了解可用的块。如果他们改用from mcpi import block
,则可以键入walls = block.
,然后会弹出一个自动完成列表。
这是非常糟糕的做法,原因有两个:
对于第1点:让我们看一个例子:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
在这里,看到代码,没有人会得到关于从哪个模块的想法b
,c
并且d
实际上属于。
另一方面,如果您这样做,则:
# v v will know that these are from module1
from module1 import b, c # way 1
import module2 # way 2
a = b + c - module2.d
# ^ will know it is from module2
这对您来说更加清洁,加入团队的新人也会有更好的主意。
对于第2点:让两者都说出来,module1
并将module2
变量as设置为b
。当我做:
from module1 import *
from module2 import *
print b # will print the value from module2
此处的价值module1
丢失。很难调试为什么即使b
声明了module1
并且我已经编写了期望我的代码使用的代码也无法正常工作的原因module1.b
如果不同模块中的变量相同,并且不想导入整个模块,则可以执行以下操作:
from module1 import b as mod1b
from module2 import b as mod2b
作为测试,我创建了一个模块test.py,其中包含2个函数A和B,分别打印“ A 1”和“ B 1”。使用以下命令导入test.py之后:
import test
。。。我可以将两个函数分别作为test.A()和test.B()运行,并且“ test” 在命名空间中显示为模块,因此,如果我编辑test.py,可以使用以下命令重新加载它:
import importlib
importlib.reload(test)
但是,如果我执行以下操作:
from test import *
在命名空间中没有对“测试”的引用,因此在编辑后(据我所知),没有办法重新加载它,这在交互式会话中是一个问题。而以下任何一项:
import test
import test as tt
将在名称空间中分别添加“ test”或“ tt”作为模块名称,这将允许重新加载。
如果我做:
from test import *
名称“ A”和“ B”作为功能出现在名称空间中。如果我编辑test.py,并重复以上命令,则不会重新加载功能的修改版本。
并且以下命令引发错误消息。
importlib.reload(test) # Error - name 'test' is not defined
如果有人知道如何重新加载加载有“ from module import *”的模块,请发布。否则,这是避免使用该表格的另一个原因:
from module import *
如文档中所建议,您(几乎)永远不要import *
在生产代码中使用。
虽然*
从模块中导入很不好,但是从包中导入*更糟。默认情况下,from package import *
导入包的定义的任何名称__init__.py
,包括先前import
语句加载的包的任何子模块。
但是,如果包的__init__.py
代码定义了名为的列表__all__
,则将其视为from package import *
遇到时应导入的子模块名称的列表。
考虑以下示例(假设在中__all__
未定义sound/effects/__init__.py
):
# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround
# in your module
from sound.effects import *
最后一条语句会将echo
和surround
模块导入当前的名称空间(可能会覆盖先前的定义),因为它们是在执行语句sound.effects
时在包中定义的import
。