代码之家  ›  专栏  ›  技术社区  ›  kamasheto

需要使用全名时为什么要导入?

  •  9
  • kamasheto  · 技术社区  · 14 年前

    import foo.bar
    

    但有什么不合理的是,为什么我需要使用全名每当我想使用酒吧?如果我想使用全名,为什么需要导入?使用全名不能立即描述我正在寻址的模块吗?

    这似乎有点多余 from foo import bar 那是什么时候 import foo.bar 我应该做的。还有一点模糊,为什么我要导入时,我要使用全名。

    8 回复  |  直到 14 年前
        1
  •  23
  •   David Z    6 年前

    问题是,尽管Python import 声明旨在 进口 语句实际上只不过是编译器的一个提示。它基本上为完全限定的类名设置了一个别名。例如,当你写

    import java.util.Set;
    

    它告诉编译器在整个文件中 Set 你是说 java.util.Set . 如果你写信 s.add(o) 哪里 s 是类型的对象 ,编译器(或者更确切地说,链接器)出去并找到 add 中的方法 Set.class 并加入一个引用。

    import util.set
    

    姓名 ,它们是真的 物体 ,当你写作时 util.set 在代码中,它指示Python访问名为 util set . Python的工作 进口 util/__init__.py ,使用其中的代码定义对象的属性,并将该对象绑定到名称 . 类似地,中的代码 util/set.py 用于初始化绑定到的对象 实用程序集 __import__ 所有这些,事实上 import util.set 基本上相当于

    util = __import__('util.set')
    

    关键是,当你导入一个Python模块时,你得到的是一个对应于顶级包的对象, . 为了获得 实用程序集 您需要经历这些,这就是为什么在Python中似乎需要使用完全限定名的原因。

    实用程序集 更简单的名字,即 声明,你可以

    set = util.set
    

    从那时起你就可以 设置 如果不是这样的话你会写的 实用程序集 . (当然,这掩盖了内置的 设置

    from util import set
    

    import util.set as set
    

    这仍然会导入包 使用模块 设置 在当前范围中,它创建一个变量 设置 指的是 实用程序集

    _util = __import__('util', fromlist='set')
    set = _util.set
    del _util
    

    在前一种情况下,或者

    _util = __import__('util.set')
    set = _util.set
    del _util
    

    在后者中(尽管两种方法基本上做相同的事情)。这种形式在语义上更像Java的 语句:它定义了一个别名( 实用程序集 ).

        2
  •  6
  •   Donald Miner    14 年前

    如果您愿意,可以缩短:

    import foo.bar as whateveriwant
    

    使用全名可以防止具有相同命名子模块的两个包相互碰撞。

        3
  •  4
  •   unutbu    14 年前

    io :

    In [84]: import io
    
    In [85]: io
    Out[85]: <module 'io' from '/usr/lib/python2.6/io.pyc'>
    

    scipy 打电话 木卫一

    In [95]: import scipy.io
    
    In [96]: scipy.io
    Out[96]: <module 'scipy.io' from '/usr/lib/python2.6/dist-packages/scipy/io/__init__.pyc'>
    

    如果您想在同一个脚本中使用这两个模块,那么名称空间是区分这两个模块的方便方法。

    In [97]: import this
    The Zen of Python, by Tim Peters
    ...
    Namespaces are one honking great idea -- let's do more of those!
    
        4
  •  3
  •   Jim Carroll    14 年前

    在Python中,导入并不只是表示您可能会使用某些东西。导入实际上是在模块级执行代码。您可以将导入视为“解释”和创建函数的时刻。任何在init.py级别或不在函数或类定义中的代码都会发生。

    导入还生成整个模块名称空间的廉价副本,并将其放入文件/模块/无论导入到何处的名称空间中。IDE会有一个您可能开始键入以完成命令的函数列表。

        5
  •  3
  •   Mark Ransom    14 年前

    Python哲学的一部分是 explicit is better than implicit

    我还猜测,如果导入是自动的,那么包初始化会困难得多,因为它不会在代码中一致地完成。

        6
  •  3
  •   JAB    14 年前

    您对Python导入的工作方式有点困惑(在Python中,您不能简单地用全名引用模块中的某个内容,这与Java不同;无论您计划如何引用导入的项,都必须首先导入模块。尝试键入 math.sqrt(5) 在解释器中不导入 math math.sqrt 先看看会发生什么。

    不管怎样。。。原因是什么 import foo.bar foo.bar 而不仅仅是 bar 是为了防止意外的命名空间冲突。例如,如果你这样做了呢 ,然后 import baz.bar ?

    当然,你可以选择 import foo.bar as bar from foo import bar . (编辑:除非你想导入方法和变量。那你就得用 from ... import ... 导入foo.bar 如果 酒吧 是方法或变量。)

        7
  •  1
  •   mkneissl    14 年前

    除了Java,Python import foo.bar 声明,您将使用 foo.bar .

    这与Python的哲学相吻合,即显式优于隐式。有更多的编程语言使模块间的依赖关系比Java更明确,例如Ada。

        8
  •  1
  •   ʇsәɹoɈ    14 年前

    from foo import bar
    
    import foo.bar as bar
    
    import foo.bar
    bar = foo.bar
    
    from foo import *
    

    • 它们有助于向人类和工具发出信号,说明模块所依赖的包。
    • 它们避免了在运行时动态确定哪些包必须被加载(也可能被编译)的开销。
    • 它们使程序员能够控制进入他工作的名称空间的内容。