gru*_*czy 203
因为它会在你的命名空间中放入很多东西(可能会影响之前导入的其他一些对象,你不会知道它).
因为您不确切知道导入的内容,并且无法轻松找到导入某个内容的模块(可读性).
因为您无法使用酷工具pyflakes
来静态检测代码中的错误.
Fed*_*rer 45
显式优于隐式.
......当然不能与之争辩吗?
Mar*_*ani 38
你没有传递**locals()
给函数,对吗?
因为Python缺少"包括"语句,并且该self
参数是明确的,并且范围的规则相当简单,它通常是很容易在一个变量指向一个手指,告诉哪里该对象来自-没有阅读其他模块,无任何IDE(无论如何,它都以内省的方式限制,因为语言非常动态).
该import *
休息了这一切.
此外,它具有隐藏错误的具体可能性.
import os, sys, foo, sqlalchemy, mystuff
from bar import *
Run Code Online (Sandbox Code Playgroud)
现在,如果条形模块具有任何" os
"," mystuff
"等属性,它们将覆盖显式导入的属性,并可能指向非常不同的东西.__all__
在bar中定义通常是明智的 - 这说明将隐式导入的内容 - 但仍然很难跟踪对象的来源,而无需读取和解析条形模块并跟踪其导入.import *
当我获得项目的所有权时,我首先修复了一个网络.
不要误解我:如果import *
失踪了,我会哭着拥有它.但必须谨慎使用.一个很好的用例是在另一个模块上提供外观界面.同样,使用条件导入语句或在函数/类命名空间内导入需要一些纪律.
我认为在大中型项目中,或者有几个贡献者的小型项目,在静态分析方面需要最少的卫生 - 至少运行pyflakes或更好地配置正确的pylint - 以捕获几种错误之前他们发生了.
当然,因为这是python - 随意破坏规则和探索 - 但要警惕可能增长十倍的项目,如果源代码缺少纪律,那将是一个问题.
ext*_*eon 16
那是因为你正在污染命名空间.您将导入自己的命名空间中的所有函数和类,这可能与您自己定义的函数冲突.
此外,我认为使用合格的名称对于维护任务更为明确; 您可以在代码行上看到函数的来源,因此您可以更轻松地查看文档.
在模块foo中:
def myFunc():
print 1
Run Code Online (Sandbox Code Playgroud)
在你的代码中:
from foo import *
def doThis():
myFunc() # Which myFunc is called?
def myFunc():
print 2
Run Code Online (Sandbox Code Playgroud)
Fel*_*ing 10
http://docs.python.org/tutorial/modules.html
请注意,一般来说,
*
从模块或包导入的做法是不受欢迎的,因为它通常会导致代码难以理解.
假设您在名为foo的模块中有以下代码:
import ElementTree as etree
Run Code Online (Sandbox Code Playgroud)
然后在你自己的模块中你有:
from lxml import etree
from foo import *
Run Code Online (Sandbox Code Playgroud)
你现在有一个难以调试的模块,看起来它里面有lxml的etree,但实际上却有ElementTree.
这些都是很好的答案.我要补充一点,在教新人用Python编写代码时,处理import *
非常困难.即使你或他们没有编写代码,它仍然是一个绊脚石.
我教孩子们(大约8岁)用Python编程来操纵Minecraft.我喜欢给他们一个有用的编码环境来使用(Atom编辑器)并教授REPL驱动的开发(通过bpython).在Atom中,我发现提示/完成的效果与bpython一样有效.幸运的是,与其他一些统计分析工具不同,Atom并没有被愚弄import *
.
但是,让我们举个例子......在这个包装器中,他们from local_module import *
是一堆模块,包括这个块列表.让我们忽略名称空间冲突的风险.通过这样做,from mcpi.block import *
他们可以制作完整的模块类型列表,您必须查看这些块以了解可用的内容.如果他们使用了from mcpi import block
,那么你可以输入walls = block.
,然后会弹出一个自动完成列表.
了解了人们在这里提出的有效观点。但是,我确实有一个论点,有时“星号导入”可能并不总是一个坏习惯:
const.py
:
import const
,那么对于每个常量,我都必须将其称为const.SOMETHING
,这可能不是最方便的方法。from const import SOMETHING_A, SOMETHING_B ...
,那么显然它太冗长并且破坏了结构化的目的。from const import *
可能是更好的选择。这是一种非常糟糕的做法,原因有二:
对于第 1 点:让我们看一个例子:
from module1 import *
from module2 import *
from module3 import *
a = b + c - d
Run Code Online (Sandbox Code Playgroud)
在这里,看到代码,没有人会得到关于从哪个模块的想法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
Run Code Online (Sandbox Code Playgroud)
它对你来说更干净,而且新加入你的团队的人会有更好的想法。
对于第2点:假设都module1
与module2
有变量b
。当我做:
from module1 import *
from module2 import *
print b # will print the value from module2
Run Code Online (Sandbox Code Playgroud)
这里的值module1
丢失了。很难调试为什么代码不起作用,即使b
是在声明中module1
并且我已经编写了期望我的代码使用的代码module1.b
如果您在不同的模块中有相同的变量,并且您不想导入整个模块,您甚至可以这样做:
from module1 import b as mod1b
from module2 import b as mod2b
Run Code Online (Sandbox Code Playgroud)