Python *导入

时间:2011-05-04 00:25:29

标签: python pyqt python-import

我一般都被告知以下是不好的做法。

from module import *

主要推理(或者我被告知)是你可以导入一些你不想要的东西,它可能会影响另一个模块中类似命名的函数或类。

然而,那么PyQt

from PyQt4.QtCore import *

我见过的每个例子都是用这种方式编写的,主要是因为从Qt导出的所有内容都以“Q”开头,所以它不会影响任何东西。

什么是共识?使用*导入总是不好吗?

编辑:

为了清楚起见,这个问题专门针对使用PyQt4。它与我设计其他项目的方式无关。

基本上,我发现对PEP8的编码提高了我的代码可读性,除了导入PyQt4之外,所以我一直忽视纯粹主义者的皱眉。但是现在我的开发小组正在决定一个大会,我想知道这是否是“实用性超过纯度”的情况,或者我是否应该把它搞砸并处理怪异的PyQt4进口

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

8 个答案:

答案 0 :(得分:9)

这可能会变成一场宗教战争。这是一个问题,你是想要明确,还是想避免过于冗长。一般来说,在Zen of Python之后,最好是明确的,但有时人们只是觉得列出特定模块的每个导入都不切实际。

答案 1 :(得分:5)

我的一般规则是,如果我没有写模块,我不会全部导入。我最大的担心实际上是编写可能已在导入模块中定义的局部变量。因此,为了不必输入长模块名称,我使用import作为功能。以您的模块为例,我将执行以下操作:

import PyQt4.QtCore as qt

话虽如此,我写了许多支持模块,我将导入所有内容。与pyqt模块一样,我使用描述性名称命名它们,以帮助显示它来自哪个模块。

根据评论进行修改
 当我使用import *时,我的支持模块不包含可以创建新实例的类或任何东西。它们往往是仅修改现有实例的函数组。为了帮助澄清我的观点:如果我是源代码的所有者并且我将成为主要维护者,我将使用import *否则我将使用import作为。

我使用导入功能的另一个原因是允许我模拟模块以进行调试。在我正在进行的项目中,我使用pyVisa与许多GPIB设备进行通信。当我没有连接到设备GPIB网络时,我可以使用dummy_visa模块写入stdout(以验证我发送的格式正确)并返回一个随机数(以测试我的应用程序)。见下文

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

答案 2 :(得分:5)

对于已在命名约定中包含命名空间的模块(例如PyQT的Q*),显式异常是完全合理的。但是,我建议明确默认仍然是“不要使用它”,只需在编码指南中列出此例外。

import *在应用程序中用作命名空间操作技巧时也是可以接受的(我熟悉的两种形式是在纯Python版本末尾导入的可选C加速模块,并在__init__中“展平”包名称空间。关键点在于导入模块和导入的模块在同一组开发人员的控制之下,因此避免命名空间冲突完全在他们的控制之内。

最后一个例外是为了方便交互式提示。

在其他情况下,最好是导入特定名称或通过模块名称间接引用它们(或者,如果有一些常见的参考项,则同时执行这两项:

导入模块#可以访问任何内容    从模块导入a,b,c#但我们引用了很多,所以直接检索它们

答案 3 :(得分:3)

教程,chapter 6

  

请注意,一般来说,从模块或包导入*的做法是不受欢迎的,因为它经常会导致代码难以理解。但是,可以使用它来保存交互式会话中的输入。

教程,chapter 10

  

请务必使用import os样式而不是os import *。这将使os.open()不会影响内置的open()函数,该函数的运行方式大不相同。

所以似乎有时候这绝对是一个坏主意;大部分时间都不是最好的主意;并且在您想要输入较少的情况下是可接受的快捷方式,例如在交互式会话中。

答案 4 :(得分:3)

我发现import *被滥用,并且可能会成为一种维护问题,所以我为此避免了这一点以及你说的其他原因。那说我觉得短暂的互动会话是可以的,例如from pylab import *

在生产代码中,对于计划使用许多符号的PyQt4.QtCore这样的包,我会使用以下语法之一来明确符号来自哪个命名空间:

from PyQt4 import QtCore
# explicit where the symbol came from
QtCore.QTime()

import PyQt4.QtCore as QT
# less desirable since you need to look in the header to find out what QT is
# but I still prefer it to import *
QT.QTime()

答案 5 :(得分:3)

一般情况下,如果您要使用from X import Y,最好明确说明您要导入的内容。这不仅仅是因为它更安全,而且还因为它使您的代码更具可读性(并且对您正在使用的第三方模块的升级不会有太多可能会偶然破坏您的代码)。

在一些演示大包的代码示例中,例如Qt或matplotlib,示例将使用from module import *,因为它们通常只从一个模块导入,并且它保存了输入并让它们的示例代码达到了目的。没有理由你不能在你的代码中执行它,但至少要适度使用它,特别是如果它在大源文件中或其他人会查看你的代码。

答案 6 :(得分:2)

PyQt设计是桥下的水。我不确定它是最好的东西,但它可能受到Qt设计方式的影响。 AFAIK,Qt历史上没有使用C ++命名空间(我不确定它现在是否使用它们),因此不得不使用前缀。但所有这些设计决策可能都发生在十多年前,这不应该影响您的设计决策现在

我知道如果我现在正在设计一个库,我肯定会选择使用包命名空间(你可以在Python中显式导入)而不是前缀。假设我的前缀是Pfx - 如果库用户不关心每次需要函数时写PfxFunc(),他肯定不关心Pfx.Func()中的额外字符,特别是当他可以使用时导入具有特定符号名称以进一步缩短。

答案 7 :(得分:1)

考虑这个案例

from foo import *
from bar import *

x=baz()

现在假设foo有一个名为baz()的函数,我们在代码中使用它,一切正常。经过了几个月或几年,bar的作者添加了一个名为baz()的函数。有人更新了egg ang bingo - 我们可能很难发现程序中的错误。

更不用说仅仅查看这三行代码,我不知道baz来自哪里而不去查看foobar

我唯一一次使用import *将在解释器中保存一些打字