【问题标题】:python: how to call a constructor in a module in a package in another package directly [duplicate]python:如何直接在另一个包中的一个包中调用一个模块中的构造函数[重复]
【发布时间】:2013-05-08 15:00:28
【问题描述】:

我正在将一些 matlab 代码移植到 python。在这种情况下,我需要使用包和模块。相关的包目录结构如下:

toppackage
    __init__.py
    subpackage
        __init__.py
        module.py
        ...

在我使用包的脚本中,我可以这样工作:

from toppackage.subpackage.module import SomeClass
s = SomeClass()

但我更喜欢这样工作:

import toppackage %somewhere at the beginning of file
s = toppackage.subpackage.module.SomeClass()

我看到这是在 numpy 中完成的。但我在文档中找不到它。我该怎么做?

提前致谢。

【问题讨论】:

    标签: python python-module


    【解决方案1】:

    您需要在__init__.py 文件中导入包含的包。

    你可以导入toppackage/__init__.py里面的包,例如:

    import toppackage.subpackage.module
    

    或者你可以只导入每个直接包含的包,所以在toppackage/__init__.py

    from . import subpackage
    

    toppackage/subpackage/__init__.py:

    from . import module
    

    仅导入顶级包不会自动使包含的包可用。在此之前,您需要在某处明确导入一次完整路径。

    numpy 包导入顶层__init__.py 中的嵌套包。

    【讨论】:

    • 是的,这行得通。然而,这个包处于快速开发阶段,我希望模块的子包经常发生变化。记住每次编辑subpackage/__init__.py 可能很麻烦。我试过from . import *,但它不起作用。作为一种可能的解决方法,我们可以这样做吗:我们可以很容易地以编程方式在子包中找到模块。假设变量module_name有一个模块的名字,我们可以导入它吗?
    • @ozi: 你只需要导入已经间接自动导入的模块。假设module 导入from . import utils,那么utils 现在已经导入并且可以访问了。这并不像你想象的那么大。
    • 应该问题不大吧。尽管如此,我还是找到了在以编程方式获取它们的路径后动态加载模块的方法:stackoverflow.com/questions/301134/…
    • 当然有,但在我看来,这有点矫枉过正。
    【解决方案2】:

    这些东西的工作原理很大程度上取决于__init__.py 中的内容。在该脚本中导入的任何内容都将成为包命名空间的一部分。

    例如,如果您的toppackage/__init__.py 为空,要访问subpackage,您需要执行以下操作:

    import toppackage
    try:
        p = toppackage.subpackage
    except AttributeError:
        print "you would see this"
    
    import toppackage.subpackage
    p = toppackage.subpackage #no error now
    

    但是,如果 toppackage/__init__.py 包含该行:

    #toppackage/__init__.py
    import subpackage
    

    那么上面的脚本不会引发异常。

    如 cmets 中所述,您还可以使用相对导入,因为您在包中:

    from . import subpackage
    

    这避免了“命名空间”冲突——例如如果您有一个名为 os 的子包,它将获取您的子包而不是 python 级别的包。

    【讨论】:

    • 最好不要使用相对导入; from . import subpackage 会更好。
    • @MartijnPieters -- 但这破坏了与 python2.4 的兼容性 ;-)
    • 我们不再那么关心 2.4 了吗? 2.6及以上,是我通常假设的。 :-)
    • @MartijnPieters -- 我主要是在开玩笑。我补充说。如果记忆正确,我相信我什至见过import toppackage.subpackage as subpackage。这实际上是我在子模块本身内部使用的形式,但我不确定我之前是否在 __init__.py 中使用过它。
    • @MartijnPieters -- 无论如何,从解释 如何 操作包的命名空间的角度来看,我喜欢第一种形式,因为你不需要解释相对进口的魔力。尽管在这种情况下,我会说“显式”相对导入可能是您所指出的最好的。
    猜你喜欢
    • 2011-01-23
    • 2020-04-17
    • 2016-07-03
    • 2010-09-22
    • 2013-09-26
    • 2020-11-01
    • 2020-06-22
    相关资源
    最近更新 更多