如何在Python3中从子文件夹(带有空的__init__.py)导入模块

14

我想从一个子文件夹中的文件调用一个函数。我希望能够静态地完成这个操作。我使用空的__init__.py文件,因为我已经读到在简单情况下它们可以是空的(而我的情况就是这样),或者从3.5开始我根本不需要它们。但我也可以填充它们。

我的文件结构如下:

test
├── callfoo.py   (main)
├── __init__.py  (empty)
└── folder
    ├── submodule.py
    └── __init__.py (empty)

callfoo.py:

#import statement wanted

def main():
    foo()

if __name__ == "__main__":
        main()

子模块.py

def foo():
    print('foo')

对于导入语句,我尝试了以下方法:

import test.folder.submodule
from test.folder import submodule
from test.folder.submodule import foo

但每个都导致ModuleNotFoundError: No module named 'test.folder'。我有点困惑,因为它们直接来自文档

import .folder.submodule -> invalid syntax importlib.import_module('test.folder.submodule') ModuleNotFoundError: No module named 'test.folder'

这个可以工作:

import importlib.util
spec = importlib.util.spec_from_file_location("submodule", "/home/.../test/folder/submodule.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)

但是我并不想动态地做它,尤其是对于几个文件。

ModuleNotFoundError: No module named x 处理了我的错误信息,但据我所知并没有处理子文件夹的情况(对于与 callfoo.py 处于同一级别的 submodule.py 文件,它可以正常工作)

有几个问题涉及从子文件夹导入,但我无法让它们为我工作。 希望我已经提供了一个非常简单的问题描述。

1个回答

15

假设我们有以下的文件夹/文件结构:

test
├── callfoo.py
└── folder
    ├── __init__.py
    └── submodule.py

1 directory, 3 files

callfoo.py:

callfoo.py:

from folder.submodule import foo

def main():
    foo()

if __name__ == '__main__':
    main()

子模块.py:

def foo():
    print('foo in submodule')

现在将自己放置于与 callfoo.py 相同级别的文件夹中,并运行:

$ python3 callfoo.py

输出:

> foo in submodule

1
非常感谢!您能告诉我为什么文档(6.4)使用顶级包,例如我的情况是test吗? - peer
1
@同行,为了运行文档中的示例,您需要正确设置sys.path。它说:“导入包时,Python会在sys.path上的目录中查找包子目录。” - Chiheb Nexus
1
如果您从与callfoo.py相同的目录运行Python,则此方法有效,但是如果callfoo.py是已安装包的一部分,并且从任意目录导入,则该方法将无效。 - aaronsnoswell
这在我家里可以运行,但是当我将其尝试在学校的电脑上运行时,它会显示找不到模块。 - Hippolippo
@Hippolippo 请查看此文档链接 - Chiheb Nexus
1
@ChihebNexus,我找到了问题所在,是我导入的方式搞砸了。 - Hippolippo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接