【问题标题】:Import parent module package导入父模块包
【发布时间】:2011-11-05 17:46:06
【问题描述】:

目录结构:

[app]
    start.py
        import package1
    [package1]
        __init__.py
            print('Init package1')
            import module1
            import subpackage1
        module1.py
            print('package1.module1')
            import package1 # this works OK
        [subpackage1]
            __init__.py
                print('Init package1.subpackage1')
                import module1
            module1.py
                print('Init package1.subpackage1.module1')
                #from package1 import subpackage1 # ImportError: cannot import name subpackage1
                #from .. import subpackage1 # ImportError: cannot import name subpackage1
                #import . as subpackage1 # SyntaxError: invalid syntax
                import package1.subpackage1 as subpackage1 # AttributeError: 'module' object has no attribute 'subpackage1'

为了避免subpackage1.module1 中的循环导入引起的问题,我想导入模块subpackage1,以便以subpackage.module2 的形式引用subpackage1 中的其他模块。因为如果我这样做from . import module2,当我尝试此导入时,module2 中的引用可能还不存在于subpackage1

我已经尝试了 4 种不同的方法 - 它们都不起作用 - 请参阅代码中的 cmets。

有什么帮助吗?

前段时间subpackage1 是顶级包并且它工作了(看看它在package1.module1 的源代码中是如何工作的。现在,当我将它向下移动一级时 - 我遇到了这个问题......我知道我可以将package1 dir添加到sys.path,但这很难看。

【问题讨论】:

  • 你正在尝试的实际上是创建一个循环导入本身。

标签: python import python-3.x


【解决方案1】:

我使用了这个 hack,它对我有用:

#import package1.subpackage1 as subpackage1 # AttributeError: 'module' object has no attribute 'subpackage1'
subpackage1 = sys.modules[__name__.rpartition('.')[0]] # parent module

或者你可以试试这个:

from package1 import subpackage1

在某些情况下有效:https://stackoverflow.com/a/24968941/248296

【讨论】:

    【解决方案2】:

    我不确定您要做什么,但如果您使用绝对导入并避免将代码放入 __init__ 模块中,您的示例可能会更容易理解。

    试试这样的:

    [app]
        start.py
            print('Start')
            from package1 import module1
        [package1]
            __init__.py
                print('Init: package1')
            module1.py
                print('Load: package1.module1')
                from package1.subpackage1 import module1
            [subpackage1]
                __init__.py
                    print('Init: package1.subpackage1')
                module1.py
                    print('Load: package1.subpackage1.module1')
                    from package1 import subpackage1
    

    运行start.py后,你应该得到如下输出:

    Start
    Init: package1
    Load: package1.module1
    Init: package1.subpackage1
    Load: package1.subpackage1.module1
    

    【讨论】:

    • 感谢您的回复,但我需要从module1 导入一些名称以在subpackage1.__init__ 中公开它们。另外我正在导入模块subpackage1.__init__,因为subpackage1 中有几个模块,我需要按特定顺序导入它们。
    • @warvariuc。一般来说,应该避免将代码放在__init__ 模块中。需要以特定顺序导入模块也有不好的代码气味。听起来您需要拆分模块,以便更有效地在模块之间共享功能。
    • 我想做得更好,但不知道怎么做。至于__init__ 中的代码,经常会在其他项目中看到这个代码——(例如scrapy)。否则,你为什么需要__init__
    • @warvariuc。需要__init__.py 文件才能使 python 将目录视为包的(一部分)。它们通常为空,但有时可能包含一些包初始化代码。尽管 可以 放入其他代码,但这不是它们的预期目的,因此许多(但显然不是全部)python 编码人员倾向于避免以这种方式使用它们。为什么你认为你需要使用它们?您要解决什么具体问题?
    • 我正在将一些全局变量从子模块导入包命名空间
    猜你喜欢
    • 2019-05-26
    • 2012-12-24
    • 2021-09-15
    • 1970-01-01
    • 2020-12-06
    • 2018-08-16
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    相关资源
    最近更新 更多