从不在“main.py”级别的笔记本中的相对导入

Posted

技术标签:

【中文标题】从不在“main.py”级别的笔记本中的相对导入【英文标题】:Relative imports from within a notebook that is not at the 'main.py' level 【发布时间】:2020-12-28 08:34:09 【问题描述】:

我的结构如下:

/src
    __init__.py
    module1.py
    module2.py
/tests
    __init__.py
    test_module1.py
    test_module2.py
/notebooks
    __init__.py   
    exploring.ipynb
main.py

我想使用 notebook 'exploring' 进行一些数据探索,为此我需要执行 module1module2 的相对导入。但是,如果我尝试运行 from ..src.module1 import funct1,我会收到 ImportError: attempted relative import with no known parent package我理解这是预期的,因为我正在运行 notebook,就好像它是一个脚本而不是一个模块一样。 p>

因此,作为一种解决方法,我主要在每次需要使用笔记本时将其文件夹外的笔记本拉到 main.py 级别,然后 from src.module1 import funct1 工作。

我知道相对导入已经有大量线程,但到目前为止我找不到更简单的解决方案来完成这项工作,而不必每次都移动笔记本。考虑到笔记本在调用时“作为脚本”运行,有什么方法可以执行这种相对导入?

【问题讨论】:

【参考方案1】:

脚本不能进行相对导入。你有没有考虑过这样的事情:

if __name__ == "__main__":
    sys.path.insert(0,
        os.path.abspath(os.path.join(os.getcwd(), '..')))
    from src.module1 import funct1
else:
    from ..src.module1 import funct1

或者使用异常:

try:
    from ..src.module1 import funct1
except ImportError:
    sys.path.insert(0,
        os.path.abspath(os.path.join(os.getcwd(), '..')))
    from src.module1 import funct1

?

【讨论】:

不,我没有考虑过。谢谢分享。 首先:笔记本不会创建变量__file__,正如其他几个线程中所证实的那样。虽然使用os.getcwd(),即os.path.abspath(os.path.join(os.getcwd(), '..'))),但我能够解决这个问题。但是,由于该过程中涉及的子模块也自己执行相对导入,所以它会变得一团糟,好像笔记本路径始终是请求其他相对导入的根路径 首先,__file__ 变量是正确的,我没有为 nb 测试它,更正了答案。其次,如果您确切地说出您的错误是什么,那就太好了,因为它对我来说很好,而我将 nb 作为脚本运行,并且模块在其包内执行相对导入。也许,你得到这个错误:“ValueError:尝试相对导入超出***包”?那么,就和nb没关系了。你可以看看***.com/questions/6323860/sibling-package-imports。 不,因为当我使用常规进程运行模块时一切正常(从 main.py 级别调用模块等,并且我有几个子文件夹和子文件夹)。即使我将相同的笔记本移动到 main.py 级别,它也运行良好,但当它们位于任何子级别时,它就不会运行。我知道“兄弟包导入”,尤其是那个著名的线程,但笔记本有一些不同。

以上是关于从不在“main.py”级别的笔记本中的相对导入的主要内容,如果未能解决你的问题,请参考以下文章

Python 包:相对导入

Python错误-ImportError:尝试使用没有已知父包的相对导入[重复]

python的相对路径导入问题

SystemError:父模块''未加载,无法执行相对导入[重复]

python 第无课笔记

获取导入模块的路径