从子文件夹导入 python

Import from subfolder python

我的项目结构如下。在api.py里面我需要一些写在上层的函数

Project1
├── model.py 
├── audio_utils.py
├── audio.py 
└── backend
     ├── static
     │      ├──js
     │      ├──img
     └── api.py

为什么我无法在api.py内部导入上层的函数? 当我尝试这样做时:

from audio_utils import *

我得到以下信息:

 No module named 'audio_utils'

您在两个目录中都有 __init__.py 个文件,对吗?

尝试from ..audio_utils import *

模块是从 sys.path 中指定的路径前缀导入的。它通常包含 '' ,这意味着将加载当前工作目录中的模块。 (https://docs.python.org/3/tutorial/modules.html#packages)

我认为您在 backend 目录中时正在开始 Python 解释。然后我认为没有办法访问上层目录中的模块——即使使用 .. (https://realpython.com/absolute-vs-relative-python-imports/#syntax-and-practical-examples_1) 也不行,除非您更改 sys.path,这将是一个非常混乱的解决方案。

我建议您创建 __init__.py 文件以指示包含它们的目录是 Python 包:

Project1
├── model.py 
├── audio_utils.py
├── audio.py 
└── backend
     |-- __init__.py
     ├── static
     │      ├──js
     │      ├──img
     └── api.py

并且始终从 Project1 目录开始解释。这样做,您应该能够像这样导入任何模块:

import model
from backed import api
import audio_utils

无论您在 Project1 中的哪个模块中编写此代码。将尝试解释 的当前目录

请注意还有 PYTHONPATH 环境变量,您可以利用它来发挥自己的优势。

请注意,对于发布您的项目,鼓励将所有模块放在一个包中(换句话说:不要将模块放在顶层)。这是为了帮助防止名称冲突。我认为这可能有助于您理解:https://realpython.com/pypi-publish-python-package/

如果以这种方式创建目录结构:

$ tree
.
├── bar
│   ├── den.py
│   └── __init__.py  # This indicates the bar is python package.
└── baz.py

1 directory, 3 files
$ cat bar/den.py 
import baz

然后在包含 bar/baz.py(顶层)的目录中,您可以启动 Python 解释并使用绝对导入:

In [1]: import bar.den                                                                                                                                                                        

In [2]: import baz                                                                                                                                                                            

In [3]: bar.den.baz                                                                                                                                                                           
Out[3]: <module 'baz' from '/tmp/Project1/baz.py'>

如您所见,我们能够导入 bar.den,这也可以从 top-level.

导入 baz