【问题标题】:How to import child module which imports parent module?如何导入导入父模块的子模块?
【发布时间】:2020-12-06 14:42:22
【问题描述】:

我的模块结构如下:

/parent
-- __init__.py
-- /child
---- __init__.py

我想在parent 中导入child,反之亦然,即:

/parent/init.py:

import child

/parent/child/init.py:

import parent

但是当我这样做时,我得到了错误No module named 'parent' in parent/child/__init__.py

【问题讨论】:

    标签: python python-module


    【解决方案1】:

    由于代码中模块的循环依赖性,您会收到该错误。

    当 python 尝试初始化您的 parent 模块时,它会看到 import child 语句,该语句将解释器引导至 child 模块,(注意 parent 模块尚未初始化)现在在子模块 @遇到 987654325@ 行,但由于父模块尚未初始化,解释器将失败并返回找不到parent 模块的错误。

    理想情况下,您应该修复循环导入来解决这个问题,但是可以克服将导入移到稍后阶段而不是将其添加到文件顶部的问题。 (例如:您可以在实际使用子模块的方法中添加 import 语句。)但不建议这样做。

    【讨论】:

    • 如何“修复循环导入”?
    • 您将不得不重新排列您的代码,以便您的父模块不依赖于子模块。
    【解决方案2】:

    在child中导入前添加父路径,这样可以找到父模块

    sys.path.append(os.path.abspath('..'))
    

    【讨论】:

    • 此解决方案仅在您直接从parent 编写代码时才有效,但如果有另一个导入parent 的“祖父”模块怎么办?然后附加路径中断(即abspath('..')将路径返回到“祖父母”而不是parent
    • @Tomergt45 如果你放一个__init__.py 文件,祖父模块可以直接导入父模块
    • 我在child 中添加了print(os.path.abspath('..')) 并一一执行它们,每个导入他们的孩子(祖父母导入父母,父母导入孩子),child 打印grandparent/parentparent 打印grandparentgrandparent 打印了它的父目录的路径
    • 所以导入现在应该可以工作了,还是有什么我不明白的地方?
    • 对不起,如果我的解释不好,当我在grandparent 中导入parent 时,它会在parent 中导入child,在child 中它会附加abspath(..) 以查找其父级,但是因为代码是从grandparent运行的,所以abspath(..)返回的是grandparent的父目录而不是child,这意味着child不能导入parent
    【解决方案3】:

    不良设计警告

    循环导入问题可能表明设计不佳

    解决方案

    您的导入不能同时在顶层。

    # /parent/child/init.py:
    
    import parent  # <-- top level
    
    # /parent/init.py:
    
    import .child  # <-- also top level
    

    常见的模式是将其中一个导入移动到使用它的地方(但不是在顶层,lul),例如:

    # /parent/child/init.py:
    
    def dupa():
        import parent  # <-- not top level
        parent.foo()
    

    另见

    Python circular importing?

    【讨论】:

    • 感谢您的评论,实际上我的父模块是utils,我的子模块是tfutils,表示tensorflow的utils,我需要utils中的一些功能在tfutils 里面,这就是我循环导入的原因
    猜你喜欢
    • 1970-01-01
    • 2016-10-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多