Python的*导入

12 投票
8 回答
2432 浏览
提问于 2025-04-16 16:56

我一般听说下面这种做法是不太好的。

from module import *

主要的理由(或者我听说的)是,你可能会导入一些你不想要的东西,这可能会遮盖掉其他模块中同名的函数或类。

但是,PyQt呢?

from PyQt4.QtCore import *

我见过的每一个例子都是这样写的,主要是因为从Qt导出的东西都以“Q”开头,所以不会和其他东西冲突。

大家的看法是什么?使用*导入真的总是不好么?

补充说明:

为了明确,这个问题特别是关于使用PyQt4的。和我设计其他项目的方式没有关系。

基本上,我发现遵循PEP8规范提高了我代码的可读性,除了在导入PyQt4时,所以到现在为止我都忽略了那些纯粹主义者的不满。但现在我的开发团队正在决定一个统一的规范,我在想这是否是一个“实用胜过纯粹”的情况,还是我应该忍受那些复杂的PyQt4导入。

from PyQt4.QtGui import QComboBox, QLineEdit, QLayout, Q;lakdfaf.......

8 个回答

5

我一般的原则是,如果我没有写这个模块,我就不全都导入。我的最大担心其实是会覆盖掉在导入模块中可能定义的本地变量。为了避免输入长长的模块名称,我会使用“导入为”的功能。以你的模块为例,我会这样做:

import PyQt4.QtCore as qt

不过,我有很多自己写的支持模块,我会全部导入。像pyqt模块,我会给它们起个描述性的名字,这样能更清楚地显示它们来自哪个模块。

根据评论进行编辑
当我使用import*时,我的支持模块里没有类或者其他可以创建新实例的东西。它们通常是一组只修改现有实例的函数。为了更清楚我的观点:如果我是源代码的拥有者,并且我会是主要的维护者,我会使用import*,否则我会使用import as。

我使用“导入为”功能的另一个原因是为了让我能够在调试时模拟模块。在我现在正在做的一个项目中,我使用pyVisa与多个GPIB设备进行通信。当我没有连接到这些设备的GPIB网络时,我可以使用一个dummy_visa模块来写入标准输出(以验证我发送的格式是否正确),并返回一个随机数(来测试我的应用程序)。见下文:

if visa_debug:
    import dummy_visa as visa
else:
    import visa
gpib = visa.Instrument("GPIB0::10")
gpib.write("MEAS:VOLT?")
5

对于那些在命名规则中已经包含命名空间的模块(比如PyQT中的Q*),特别做个例外是很合理的。不过,我建议还是要明确默认的原则是“不要使用它”,然后在你的编码指南中列出这个例外。

使用import *也是可以的,前提是它是在应用程序中作为一种命名空间操作的小技巧(我知道的两种情况是:在纯Python版本的最后导入可选的C加速模块,以及在__init__中“扁平化”一个包的命名空间)。关键是,导入模块和被导入模块都是同一组开发者控制的,因此避免命名空间冲突完全在他们的掌控之中。

最后一个例外是为了在交互式提示符下的方便使用。

在其他情况下,最好是导入特定的名称,或者通过模块名称间接引用它们(或者,如果有一些常用的项目,可以两者都做):

import module # 可以访问任何内容 from module import a, b, c # 但我们经常引用这些,所以直接获取它们

9

这有点像宗教战争,大家各有各的看法。关键在于你是想要明确表达,还是想避免写得太啰嗦。一般来说,按照Python的哲学,明确表达是更好的选择,但有时候人们觉得列出某个模块的每一个导入并不实际。

撰写回答