通配符导入应该避免吗?
我在使用PyQt的时候遇到了一些问题。如果我的导入语句是这样的:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
那么pylint会给出成百上千个“未使用的导入”警告。我不太想直接把这些警告关掉,因为可能还有其他未使用的导入是我需要注意的。还有一个选择是这样做:
from PyQt4.QtCore import Qt, QPointF, QRectF
from PyQt4.QtGui import QGraphicsItem, QGraphicsScene, ...
这样一来,我在QtGui那一行就会有9个类。还有第三个选择,就是:
from PyQt4 import QtCore, QtGui
每次使用这些类的时候,都在前面加上QtCore或QtGui的前缀。
现在我对在我的项目中选择哪种方式没有特别的偏好,不过从我的角度来看,最后一种方式似乎是最麻烦的。这里有什么常见的做法吗?有没有技术上的原因让人更倾向于使用某种风格?
6 个回答
Python文档提到:
虽然有些模块设计成在使用 import * 时只导出符合特定模式的名称,但在生产代码中这样做仍然被认为是不好的实践。
这样做可能会带来副作用,而且调试起来会非常困难。
就我个人而言,我更喜欢使用 import
而不是 from import
,因为我觉得在文件开头写一大堆声明很糟糕,这样可以让代码更易读。
import PyQt4
PyQt4.QtCore
如果模块名太长,可以使用 as
关键字给它起个短名字。例如:
import PyQt4.QtCore as Qc
使用 import *
也有一些好的情况。比如,Django 开发者通常会有很多配置文件,并且会通过 import *
来把它们连接起来:
settings.py:
FOO = 1
BAR = 2
DEBUG = False
test_settings.py:
from settings import *
DEBUG = True
在这种情况下,import *
的大部分缺点反而变成了优点。
关于你问题的标题,答案是“是的”:我建议永远不要使用 from ... import *
,我在最近的另一个回答中讨论了这个原因。简单来说,使用带有前缀的名称是很好的,而没有前缀的名称非常有限,所以你提到的“第三种选择”是最优的(因为你会使用带前缀的名称,而不是没有前缀的名称)。
使用带前缀的名称相比没有前缀的名称有很多好处,比如在测试时更容易进行伪造/模拟,减少了因为意外重新绑定而导致的错误风险,能够在“跟踪类”中“半伪造”顶层名称,以便准确记录你在使用什么,并简化像性能分析这样的活动等等——缺点几乎没有……另外,看看Python的Zen中的最后一个经典语录,输入 import this
在交互式解释器提示符下。
如果你觉得多打7个字符来写 QtCore.whatever
有点多,也可以用缩写——比如 from PyQt4 import QtCore as Cr
和 from PyQt4 import QtGui as Gu
(然后用 Cr.blah
和 Gu.zorp
)或者类似的方式。像所有缩写一样,这是一种在简洁和清晰之间的风格权衡(你更愿意把一个变量命名为 count_of_all_widgets_in_the_inventory
、num_widgets
还是 x
?通常中间的选择是最好的,但并不总是如此;-)。
顺便说一下,我不建议在一个 from
或 import
语句中使用超过一个 as
子句(可能会让人困惑),我更喜欢使用多个语句(如果有任何导入出问题,调试起来也更容易,未来如果你更改导入时也更方便编辑……)。