我是否应该使用“from numy import*”,将numpy(或pylab)用作python环境?

我是否应该使用“from numy import*”,将numpy(或pylab)用作python环境?,numpy,coding-style,python,Numpy,Coding Style,Python,我在所有python程序中都使用pylab(更具体地说是numpy)。例外情况非常罕见,如果有的话。到目前为止,我已经养成了以以下方式导入numpy的习惯: from numpy import * 这样做的好处是,它看起来就像numpy从一开始就是python的一部分。在每个脚本中导入这样的numpy有什么不好的地方吗?我的意思是,除了每个脚本/程序都需要更多的内存和更长的加载时间之外 我认为在每次从numpy发出的函数调用(例如,np.zero(3))之前,总是要编写numpy甚至np,这是

我在所有python程序中都使用pylab(更具体地说是numpy)。例外情况非常罕见,如果有的话。到目前为止,我已经养成了以以下方式导入numpy的习惯:

from numpy import *
这样做的好处是,它看起来就像numpy从一开始就是python的一部分。在每个脚本中导入这样的numpy有什么不好的地方吗?我的意思是,除了每个脚本/程序都需要更多的内存和更长的加载时间之外

我认为在每次从numpy发出的函数调用(例如,
np.zero(3)
)之前,总是要编写numpy甚至np,这是很乏味的,因为这需要我知道哪个函数来自numpy,哪个不来自。我真的不在乎zeros函数是否来自numpy或python,我只想/需要使用它


您认为哪种表示法更好?

如果numpy是您这样导入的唯一模块,那么这并不是一个大问题。永远不要在脚本中导入任何其他类似的模块(除非该模块是由您编写的,并且您知道关于它的一切,并且它相当小。例如,有时您将一个模块拆分为两个文件,以便更好地划分)

一般规则:以这种方式导入广泛使用的模块(如numpy)不会显著影响代码的可读性。但不要进口超过一种

我的规则是:我从不做这种进口。如果要经常使用的话,我总是做一些类似“importnumpyasnp”的事情

  • 使用numpy import中的
    *
    更改
    任何
    所有
    sum
    。比如说,

    any([[False]])
    # True
    all([[True, False], [False, False]])
    # True
    sum([[1,2],[3,4]], 1) 
    # TypeError: unsupported operand type(s) for +: 'int' and 'list'
    
    然而,如果使用numpy import*中的
    ,则值完全不同:

    from numpy import *
    any([[False]])
    # False
    all([[True, False], [False, False]])
    # False
    sum([[1,2],[3,4]], 1) 
    array([3, 7])
    
    通过这种方式可以找到完整的名称冲突集(感谢@Joe Kington和@jolvi) 请指出这一点):

  • 这可能会导致非常混乱的bug,因为有人正在测试或使用您的 如果Python解释器中的代码没有来自numpy import*
    ,那么它可能会完全
    与你的行为不同

  • 从模块导入*中多次导入
    可以复合
    这类碰撞甚至更多的问题。如果你改掉这个坏习惯
    对于bud,您永远不必担心这个(可能会混淆的)bug

    如果两个模块都重新定义了相同的名称,那么导入的顺序也可能很重要

    这使得我们很难找出函数和值的来源

  • 虽然可以从numpy import*使用
    ,但仍然可以访问Python的内置代码,这很尴尬:

    from numpy import *
    any([[False]])
    __builtins__.any([[False]])
    
    可读性比:

    import numpy as np
    np.any([[False]])
    any([[False]])
    
  • 正如Python的禅宗所说

    名称空间是一个非常好的主意 --让我们多用些吧


  • 我的建议是永远不要在任何脚本中使用模块导入的
    *

    我想说,知道每个函数调用来自哪里是一个优势。它使您能够更好地控制名称空间中的内容,并避免各种可能的冲突,这些冲突将是调试的难点。如果您认为将numpy导入为np是一件乏味的事情,那么请等到您有了重新定义函数名的第三方模块,并且您必须追踪到一些您没有预料到的神秘行为。

    请详细说明其他人所说的,numpy是使用
    导入*
    的一个特别糟糕的模块

    pylab
    用于交互式使用,在那里很好。没有人想在一个shell中反复键入
    pylab.zeros
    ,而他们只需要键入
    zeros
    。然而,一旦开始编写代码,一切都会发生变化。你只需输入一次,它就可能永远留在你身边,而其他人(比如一年后的你自己)可能会试图弄清楚你到底在干什么

    除了@unutbu已经说过的覆盖python的内置
    sum
    float
    int
    等,以及每个人都说过的不知道函数来自哪里之外,
    numpy
    pylab
    都是非常大的名称空间

    numpy
    在其名称空间中有566个函数、变量、类等。太多了<代码>pylab
    有930个!(对于pylab,它们来自许多不同的模块。)

    当然,很容易猜测
    数组
    是从哪里来的,但是
    数据源
    lib.utils
    呢?(如果从numpy import*

    如果你有一个稍微大一点的项目,很有可能你会在另一个文件中有一个局部变量或一个变量,它的名称类似于一个大模块中的某个东西,比如
    numpy
    。突然间,你开始更加关心你正在调用的到底是什么

    作为另一个例子,您如何区分
    pylab
    fft
    函数和
    numpy
    fft
    模块

    取决于你是否这样做

    from numpy import *
    from pylab import *
    
    或:

    fft
    是一个完全不同的东西,具有完全不同的行为!(即,在第二种情况下尝试调用
    fft
    将引发错误。)

    总之,您应该始终避免从模块导入中导入
    *
    ,但对于
    numpy
    scipy
    ,等等,这是一个特别糟糕的主意,因为它们是如此大的名称空间

    当然,所有这些都已经说过了,如果你只是在一个壳中四处摸索,试图在开始实际操作之前快速获得一些数据的绘图,那么当然,使用
    pylab
    。这就是它的用途。只是不要以任何人都不喜欢的方式编写东西
    from numpy import *
    from pylab import *
    
    from pylab import *
    from numpy import *
    
    zeros(5)