【问题标题】:import a.b also imports a?进口 a.b 也进口 a?
【发布时间】:2014-02-18 21:41:35
【问题描述】:

当我在一个包中导入一个子包时,我可以依赖父包也被导入的事实吗?

例如这行得通

python -c "import os.path; print os.getcwd()"

我不应该明确地import os 让os.getcwd 可用吗?

【问题讨论】:

  • 我不明白这个问题:如果它有效,那么问题出在哪里?
  • @freakish:是否保证适用于所有软件包?
  • @freakish:我相信他在问为什么它会起作用,它是如何起作用的,我可以依赖它等等。

标签: python python-import


【解决方案1】:

关于包有一件重要的事情需要了解,那就是被加载和可用之间是有区别的。

使用import a 加载模块a(可以是一个包)并以a 的名称提供它。

使用from a import b 加载模块a(这绝对是一个包),然后加载模块a.b 并仅此在名称b 下可用。请注意,a 也已在此过程中加载,因此应该进行的任何初始化都会发生。

使用import a.b,您可以加载两者并使其可用(在名称a 和a.b 下)。

【讨论】:

  • 但是import a 也提供了两个名称,不是吗? import os; os.path.join("this","works","without","import os.path")
  • @adsmith:这只是 os.path 的一个奇怪之处:os 包 __init__ 故意导入 path 以使其可用作 os.path。一般来说,不,这两个名称都不可用。 (还有时间编辑这个!正如 user2357112 指出的那样,我对 __init__ 的看法是错误的。)
  • 是的,这是一个特例。 os.path 由os 中的代码“手动”添加。如果a中只有b的目录结构,那么需要显式import a.b才能使b可用。
  • @MarkDickinson 谢谢,这就是我正在寻找的答案。
  • @MarkDickinson:os 不是一个包,也没有__init__。它直接与sys.modules 混淆以使import os.path 工作。
【解决方案2】:

这是个好问题。如果您查看os.py 的源代码,您会发现这一行:

sys.modules['os.path'] = path

这就是我们的模块。但是path 是什么?好吧,这取决于您的操作系统。对于 Windows,它在此块中定义:

elif 'nt' in _names:
    name = 'nt'
    linesep = '\r\n'
    from nt import *
    try:
        from nt import _exit
    except ImportError:
        pass
    import ntpath as path

    import nt
    __all__.extend(_get_exports_list(nt))
    del nt

基本上,os.path 在这种情况下是特殊的。

短版: Python 在幕后做了一些事情来生成 os.path。您可能不应该依赖它来获取其他模块。 “显胜于隐”是禅意。

【讨论】:

  • os.path 是特殊的,但导入规则不受这种特殊情况的影响。如果您执行import scipy.stats,也会发生同样的事情。 stats 子模块通常不用 scipy 导入。但是import scipy.stats 确实导入scipy。
【解决方案3】:

它有效且可靠。当你这样做时,引擎盖下会发生什么

import os.path

然后os 被导入,然后os.path。

【讨论】:

  • 这似乎是不一致的行为。为什么不只是 import os 然后去做 os.path.join 或者你有什么?
  • @adsmith 我不明白你的问题。什么不一致?我不是说要使用它,我是说它是一个功能。没有人必须使用它。
  • “应该有一种——最好只有一种——明显的方法。”但是import os 和import os.path 做同样的事情。这不符合 Python 的禅意,这也是我质疑它的原因。
  • MarkDickinson 和 Alfe 在下面的评论中回答了我。 os.path 很奇怪,因为 os 在其 __init__ 中导入它。大多数模块都不起作用,import a 也导入了 a.b
  • @adsmith 没错。在这种情况下,有两种方法恰好可以做到这一点。另请注意,实际上大多数模块都执行此类嵌套导入。
【解决方案4】:

是的,您可以依靠它始终工作。 Python 必须在命名空间中包含 os 才能使 os.path 工作。

使用from os import path 表示法是行不通的。在这种情况下,os 模块不被引入命名空间,只有path。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    相关资源
    最近更新 更多