我是否需要将 __init__.py 放置在通向我的类的目录树中的每个目录中?

sat*_*ish 5 django import module python-3.x

我正在使用 Python 3.6 构建 Django 项目。我已经创建了这个目录结构...

project
- manage.py
- scripts
  - run_commands.py
- commons
  - util
    - __init__.py
    - my_class.py
Run Code Online (Sandbox Code Playgroud)

init.py的内容是

from . import my_class
Run Code Online (Sandbox Code Playgroud)

在另一个班级中,我尝试像这样导入我的 MyClass

from commons.util import MyClass
Run Code Online (Sandbox Code Playgroud)

但我收到这个错误

ModuleNotFoundError: No module named 'commons'
Run Code Online (Sandbox Code Playgroud)

我是否正确创建了init .py ?

Rei*_*ica 4

看起来问题是MyClass不位于commons.util,因为您只导入了名为 的模块my_class,而不是类本身。

相反,该文件commons/util/__init__.py应包含以下导入:

from .my_class import MyClass
Run Code Online (Sandbox Code Playgroud)

我认为这不会解决您的问题,因为您会收到与所示错误不同的错误,但最终您收到此错误。

更新

首先,我建议阅读这个答案,以获得关于导入如何在 python 中工作的良好解释。

基本上,当您执行时,解释器会扫描名为 的模块from commons.util import MyClass的内容。 我假设您没有设置包含您的项目文件夹,因此.sys.pathcommons
sys.pathModuleNotFoundError

太长了;你有2个选择:

  • 手动设置sys.pathrun_commands.py检查您的项目文件夹(不要这样做!)
  • 使用Django的Command

要使用 Django 的Command类,您需要调整项目文件夹,如下所示:

project
- manage.py
- commons
- management
  - commands
    run_commands.py     
  - util
    - __init__.py
    - my_class.py
Run Code Online (Sandbox Code Playgroud)

现在在 run_commands.py 中:

from django.core.management.base import BaseCommand

from commons.util import MyClass

class Command(BaseCommand):
    def handle(*args, **options):
        print("handling", MyClass)
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令执行新命令:

python3 manage.py run_commands
Run Code Online (Sandbox Code Playgroud)