[英]Python function import not working in Django using Spyder
我的 Django 项目具有以下文件夹结构,其中controllers
是我保存所有自定义.py
文件的地方:
C:.
│ db.sqlite3
│ manage.py
│
├───myApp
│ │ admin.py
│ │ apps.py
│ │ forms.py
│ │ models.py
│ │ tests.py
│ │ urls.py
│ │ views.py
│ │ widgets.py
│ │ __init__.py
│ │
│ ├───controllers
│ │ │ helpers.py
│ │ │ function.py
│ │ │ __init__.py
│ │ │
在controllers/function.py
我想导入文件helpers.py
。
场景 1:如果我输入from .helpers import foo
并在 Django 中运行它,那么我可以导入 helpers.py,但是如果我在 Spyder 中运行相同的导入,那么我得到: ImportError: attempted relative import with no known parent package
场景 2:如果我输入from helpers import foo
(没有“点”)并在 Django 中运行它,那么我得到: ModuleNotFoundError: No module named 'helpers'
but it works in Spyder!
我在这里缺少什么路径(或相对路径)。 我需要能够在 Django 和 Spyder 中运行一个 python 脚本,而不必删除.
到处。
问:“如果我在 Spyder 中运行相同的导入”=> 你的意思是在 spyder 的集成 python shell 中吗? 答:“正确”
那么就值得期待了。
在functions.py 模块中,您可以使用相对导入(这实际上是您想要的),因为它将相对于当前模块(“functions.py”)进行解析。
当您在交互式 shell 中时,您不在包中的模块中,因此相对导入不能在这里工作,您必须使用绝对导入(或相对于当前工作目录的导入,这应该是成为你sys.path
第一个——当然除非有东西(IDE 或其他)弄乱了它。
爱荷华州:
sys.path
匹配的限定路径编辑
我不完全理解“显式相对导入”和“限定路径”的意思
“显式相对导入”: from .helpers import foo
- 它是相对导入(相对于functions
模块),并且是显式的(显式使用的语法意味着“在与我和我相同的包中查找‘helpers’模块或子包在同一级别")
“合格的路径”:嗯,是的,我猜不是最好的公式。 我的意思是使用从包顶部到模块的完整 python 限定路径的“或多或少绝对”导入。 关键是什么构成“您的包的顶部”取决于您的sys.path
,而这又可能(或不,取决于几个因素)取决于您当前的工作目录。
默认情况下,python 在sys.path
第一个位置插入当前目录。 然后它使用sys.path
来查找模块或包(警告: sys.path
列出的路径不应是包的完整路径,而是包含包的目录的路径)。
IOW,如果你打开一个终端,cd 到你的 django 的项目根目录并启动一个(标准)python shell,你的项目的根将在sys.path
在第一位,你的helpers
模块的限定名称将是myapps.controllers.helpers
。 但是,如果您在myapps
那么完整路径将是controllers.helpers
...
唯一明智的方法实际上是确保您的sys.path
永远不会直接包含任何项目的包路径(IOW 始终从项目的根目录运行您的代码)。 这不仅解决了那些讨厌的导入问题,还避免了臭名昭著的“双重导入陷阱”
“在functions.py 模块中,您可以使用相对导入”。 你的意思是我可以使用 .?
是的。 实际上,您甚至应该使用它,除非您有令人信服的理由不使用它,因为它会防止在您的sys.path
之前出现的另一个同名模块对helpers
模块的潜在影响 - 并且它非常明确地说明了哪个helpers
模块或您要从中导入的包。
这就是我在场景 1 中所做的,它在 Spyder 中不起作用。
正如我在评论已经mentionned,“确实在Spyder的不工作”是不够的,说不清楚什么是错的,因为我们不知道自己在做什么是“不以Spyder的工作” -也没有确切的错误信息和完整的回溯 FWIW,这两者通常都是“不起作用”问题所必需的(当然,除非问题很明显)。
但是如果它(正如我所理解的)“在 Spyder 中启动一个 python shell 并from . helpers import xxx
”那么它确实不会“工作” - 你只能在模块代码中使用这种语法,并且模块必须是一部分一个包,并且包含这个包的目录必须在你的sys.path
。
这就是为什么在 python shell 中,您必须使用绝对导入(“from xxx import yyy”)。 但是,哪个确切路径取决于您的sys.path
- 这部分取决于您当前的工作目录(至少对于普通的 Python shell - 我不使用 Spyder,所以我不知道它在您背后做什么)。
现在,如果 Spyder 不是完全脑残,它应该使用 django 项目的根作为sys.path
第一个元素(或者至少在sys.path
有这个目录),所以完整的限定路径( from myapp.controllers.helpers import foo
)应该工作。 如果没有,请检查您的 cwd( os.getcwd()
)和您的sys.path
,并使用以下内容编辑您的问题:
此外,您可能想阅读一些关于 Python 导入系统的文档——公平地说,有时它可能是一个特大号的 PITA。
一个 Try except 子句应该这样做:
try:
from .helpers import foo
except ImportError:
from helpers import foo
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.