Python 尝试导入包时发生ModuleNotFoundError
my_controller.py如下所示: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'
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