Python 尝试导入包时发生ModuleNotFoundError

Python 尝试导入包时发生ModuleNotFoundError,python,Python,my_controller.py如下所示: from models import Person david = Person('David') 我的项目结构是 app ├── controller │ └── my_controller.py │ └── models └── __init__.py └── person.py 我一定是做错了什么,因为我老是犯错误 ModuleNotFoundError: No module named 'models'

my_controller.py如下所示:

from models import Person

david = Person('David')
我的项目结构是

app
├── controller
│   └── my_controller.py
│   
└── models
    └── __init__.py
    └── person.py
我一定是做错了什么,因为我老是犯错误

ModuleNotFoundError: No module named 'models'    
将class Person导入my_controller.py的正确方法是什么


PS我正在ubuntu上工作

您需要使用相对导入

from . import models
或者最好导入您将使用的模型,因为它不会在视觉上与django.db.models冲突

from django import forms
from .models import VolunteerBasicInfo

class BasicInfoCollectionForm(forms.ModelForm):

    class Meta:

        model = VolunteerBasicInfo
        ...

您也不需要将class
Meta

作为用户方括号,我假设您将
应用程序
作为一个包,将
控制器
模型
作为不同的模块

import sys
import os

sys.path.append(os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..')
))

from models.person import Person

x = Person()
要实现包结构,您需要在根目录(即此处的
app
)中具有
\uuuu init\uuuuuuuuuuuuuuupy
,并在每个模块内部具有
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuupy

之后,您可以将一个模块的函数/类导入其他模块,而无需进行相对导入

我测试了与上述建议相同的问题结构

结构如下所示:

├── app
├── __init__.py
├── controllers
   ├── __init__.py
   ├── my_c.py
└── models
   ├── __init__.py
   └── my_m.py

  • 所有的
    \uuuuu init\uuuuuuuuuupy
    都是空的

  • my_m.py
    的内容是:

  • my_c.py
    的内容是:
  • 执行时:

    • python3-m控制器。我的c
      应用程序内部
  • 输出为:

    • 导入的模型

如果有帮助,请告诉我。

如果您不想更改任何结构,并且希望执行
my_controller.py
,则需要将访问权附加到公用文件夹,以便它可以导入任何相邻的模块

import sys
import os

sys.path.append(os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..')
))

from models.person import Person

x = Person()

如果您只是在shell中运行该文件,那么它非常简单。其想法是,您希望从项目中的“根”目录开始

首先,在
app/
目录中添加一个空的
\uuuu init\uuuu.py
文件

其次,将您在my_controller.py中的导入更改为从models.person导入的
,而不是从models导入的

来自models.person导入person
大卫=人(“大卫”)
最后,将cd放入
app/
目录,运行这个坏男孩

$python3-m controller.my\u controller.py
如果这不起作用,那么也将您的
PYTHONPATH
设置为
/app
,如下所示:

export PYTHONPATH=$PYTHONPATH:/my/dir/app/venv/bin

然后再次尝试第一个bash命令。

如果文件夹结构如下所示

app
├── __init__.py
│   
├── controller
│   └── my_controller.py
│   └── __init__.py
│   
└── models
    └── __init__.py
    └── person.py
您的根目录是
app
文件夹,您可以在
my_controller.py
中使用

from app.models.person import Person

if __name__ == '__main__':
    david = Person('David')
然后,如果在shell中运行该程序,则首先导航到
app
的父文件夹并使用

PYTHONPATH=. python app/controller/my_controller.py
您似乎在
应用程序
控制器
文件夹中缺少一个
\uuuu init\uuuuuuuuuuuupy
,以及正确的导入路径

为什么使用这种方法

\uuuu init\uuuuu.py
文件是将其他文件夹中的代码视为Python模块并允许导入所必需的。
如果uuuu name_uuu='\uuuuu main_uuu':
不是必需的,但是很好的练习,请阅读更多内容,例如。现在你可能会问自己,
PYTHONPATH=。
的意思是什么。它将从中执行代码的文件夹设置为根目录。使用它,您需要来自..的
。。作为导入路径导入
。这有助于保持一个干净的导入结构,显示项目的全部范围,并使添加
tests
文件夹变得容易:)

我希望我能帮助你

当我尝试这个的时候,一开始我和你的错误是一样的 经过多次调试,我发现我的一个_init_uupy.py包含一些我没有添加的异常代码,它是:
from models import person

因此,当我从那里删除它时,它会成功运行,但只有当我从根目录运行它时,如下图所示

甚至我也尝试了几种从当前工作目录运行它的方法,将cwd更改为“app”或在我的例子中更改为“practice”,但随后它开始向我显示一个错误
modulenofounderror:没有名为“app”的模块

"

但现在,我希望你得到解决方案

注意:=您还会看到其他几个文件,它是由我的IDE或python本身添加的。因此,您不必担心添加这些文件

my_controller.py中的代码:-

来自app.models导入人员

person.first()

py模块包含一个名为first()的函数


使用的IDE:-PyCharm

试试
app.models
,也许可以。尝试使用
python-m controller从
app
目录导入Personstry运行脚本。my_controller
明白了:我们应该知道init.py中包含的内容吗?您可以添加用于运行
app
的python命令吗?我不与Django合作,我不介意更改结构。最佳实践是什么?理想的做法是有一个分支,父文件夹只依赖于子模块,而不依赖于相邻模块,但如果您将执行点设置为
app/app.py
,它将允许循环导入,这在flask/django上很常见;不是那么糟糕,但这是半代码风格的选择,而不是最佳实践。
PYTHONPATH=. python app/controller/my_controller.py