【问题标题】:Difference between "import X" and "from X import *"? [duplicate]“导入 X”和“从 X 导入 *”之间的区别? [复制]
【发布时间】:2012-08-29 13:17:53
【问题描述】:

在 Python 中,我不太清楚以下两行代码之间的区别:

import X

from X import *

他们不都只是从模块 X 中导入所有内容吗?有什么区别?

【问题讨论】:

  • 你怎么知道有区别?
  • 我认为这主要是一个命名空间问题...import X 允许您维护单独的命名空间...而from X import * 将它们放在本地命名空间中
  • 如果您不知道 from X import * 导入的内容,请不要使用它。如果你知道它进口什么......不要使用它。你只是在污染你的命名空间。

标签: python import difference


【解决方案1】:
import X

在本地命名空间中创建一个引用模块对象的标签。

from X import *

直接在本地命名空间中为X 模块的每个成员属性创建一个标签。

这两个操作都将X 添加到sys.modules,是的,但是对本地命名空间的影响是不同的。

【讨论】:

    【解决方案2】:

    import X:这会将所有内容导入为X.var1X.var2

    from X import * :这会将所有内容导入为var1var2 等,即它会淹没本地命名空间

    查看两次调用后的区别:

    >>> import math
    >>> len(globals())  
    5                          #no of variables in namespace
    >>> globals()
    {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'math': <module 'math' from '/usr/local/lib/python2.7/lib-dynload/math.so'>, '__package__': None}
    >>> 
    >>>
    >>> from math import *
    >>> len(globals())
    47                     #no of variables in namespace
    >>> globals()
    {'pow': <built-in function pow>, 'fsum': <built-in function fsum>, 'cosh': <built-in function cosh>, 'ldexp': <built-in function ldexp>, 'hypot': <built-in function hypot>, 'acosh': <built-in function acosh>, 'tan': <built-in function tan>, 'asin': <built-in function asin>, 'isnan': <built-in function isnan>, 'log': <built-in function log>, 'fabs': <built-in function fabs>, 'floor': <built-in function floor>, 'atanh': <built-in function atanh>, 'sqrt': <built-in function sqrt>, '__package__': None, 'frexp': <built-in function frexp>, 'factorial': <built-in function factorial>, 'degrees': <built-in function degrees>, 'pi': 3.141592653589793, 'log10': <built-in function log10>, '__doc__': None, 'math': <module 'math' from '/usr/local/lib/python2.7/lib-dynload/math.so'>, 'asinh': <built-in function asinh>, 'fmod': <built-in function fmod>, 'atan': <built-in function atan>, '__builtins__': <module '__builtin__' (built-in)>, 'copysign': <built-in function copysign>, 'cos': <built-in function cos>, 'ceil': <built-in function ceil>, 'atan2': <built-in function atan2>, 'isinf': <built-in function isinf>, 'sinh': <built-in function sinh>, '__name__': '__main__', 'trunc': <built-in function trunc>, 'expm1': <built-in function expm1>, 'e': 2.718281828459045, 'tanh': <built-in function tanh>, 'radians': <built-in function radians>, 'sin': <built-in function sin>, 'lgamma': <built-in function lgamma>, 'erf': <built-in function erf>, 'erfc': <built-in function erfc>, 'modf': <built-in function modf>, 'exp': <built-in function exp>, 'acos': <built-in function acos>, 'log1p': <built-in function log1p>, 'gamma': <built-in function gamma>}
    

    【讨论】:

      【解决方案3】:

      存在差异,有些很简单,有些需要更多解释。

      import X 只是导入整个模块(阅读:“运行模块”),并在本地范围内为其分配一个名称。该名称可以这样命名:import X as Y

      from X import * 默认将模块X 的所有属性 导入本地范围。以下是不同用法的示例:

      # Assume that module `X` contains an `opendb` function
      import X
      X.opendb('Y')
      
      # VS.
      from X import *
      opendb('Y')
      

      当模块定义__all__ 时,稍微更复杂。这会将from X import * 的语义更改为“导入__all__属性 中列出的所有内容。”这允许模块编写者控制从他们的模块中导出哪些函数和对象。

      【讨论】:

        【解决方案4】:

        import x之后,可以引用x中的东西,比如x.something。在from x import *之后,你可以直接引用x中的东西,就像something一样。因为第二种形式将名称直接导入本地命名空间,如果您从许多模块中导入内容,它可能会产生冲突。因此,不鼓励使用from x import *

        您也可以使用from x import something,它只将something 导入本地命名空间,而不是x 中的所有内容。这更好,因为如果您列出您导入的名称,您就可以准确地知道您正在导入什么,并且更容易避免名称冲突。

        【讨论】:

        • 有什么更好的:import x 以后 x.my_function(arguments),或者 from x import my_function 以后 my_function(arguments)?
        • 我更喜欢前者,但两者都被广泛使用并且可以接受。
        【解决方案5】:

        from X import * 将模块 X 中的所有元素导入当前命名空间。 import X 导入 X 但不“合并”命名空间。例如:

        模块 X:

        def foo(): pass
        BAR = 12
        

        您的代码:

        from X import *
        foo() # calls X.foo
        print BAR # prints 12
        

        或者:

        import X
        X.foo()
        print X.BAR
        

        【讨论】:

          【解决方案6】:

          让我们用这个作为我们模块定义的例子

          def my_func():
              return 1
          

          from 导入会将所有内容拉入当前命名空间

          from X import *
          print my_func()
          

          正常导入会在当前命名空间中创建一个名为 X 的模块对象

          import X
          print x.my_func()
          

          除了 from X import my_func 之外,还可以用于仅导入该功能。

          【讨论】:

            【解决方案7】:

            你应该永远使用from X import *,除非你真的知道你在做什么。您可以从模块 X 中获取与来自另一个模块甚至您自己的程序的符号冲突的符号。我对该规则的唯一例外是有时from math import *

            您可以使用from X import y 形式从模块中获取单个事物。

            如果您使用import X 表单,您不仅可以显式使用模块X.y,而且如果您对模块进行了更改并需要重新导入它,您现在可以使用reload 函数。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-04-06
              • 2011-06-10
              • 2016-08-29
              • 1970-01-01
              • 2013-06-14
              • 2018-03-19
              • 1970-01-01
              • 2012-01-14
              相关资源
              最近更新 更多