在Python(/Django)中强制使用不一致的文件导入路径
我最近在Django(Python)中的导入遇到了一些问题。。。最好使用文件关系图进行解释:在Python(/Django)中强制使用不一致的文件导入路径,python,django,import,path,Python,Django,Import,Path,我最近在Django(Python)中的导入遇到了一些问题。。。最好使用文件关系图进行解释: - project/ - application/ - file.py - application2/ - file2.py 在project/application/file.py中,我有以下内容: def test_method(): return "Working" 当我尝试从上面导入方法时,问题出现在project/applicatio
- project/
- application/
- file.py
- application2/
- file2.py
在project/application/file.py中,我有以下内容:
def test_method():
return "Working"
当我尝试从上面导入方法时,问题出现在project/application2/file2.py中:
from application.file import test_method
通常有效,但有时无效
from project.application.file import test_method
确实有效,但这违反了Django的可移植性准则,因为项目文件夹必须始终被称为相同的文件夹
我不介意,但事实上,这个问题的发生是不一致的,大多数情况下省略project
是可以的,但偶尔不会(据我所知,没有理由)
我几乎可以保证我在做一些愚蠢的事情,但是有人经历过吗?我是否最好将项目
放在所有相关导入之前,以保持一致性?老实说,项目
文件夹名称不太可能改变,我只是希望尽可能遵循指导原则。导入要找到模块,它需要在sys.path中。通常,这包括“”,因此它搜索当前目录。如果您从project加载“应用程序”,它会找到它,因为它位于当前目录中
好吧,这是显而易见的。一个令人困惑的地方是Python会记住加载了哪些模块。如果加载应用程序,则加载导入应用程序的application2,模块“application”已加载。它不需要在磁盘上找到它;它只使用已经加载的一个。另一方面,如果您还没有加载应用程序,它将搜索它,但找不到它,因为它不在加载它的目录(“.”)中,也不在路径中的任何其他地方
这可能导致一种奇怪的情况,即导入有时有效,有时无效;它只有在已经加载的情况下才能工作
如果您希望能够将这些模块作为“应用程序”加载,则需要将project/附加到sys.path
(相对导入听起来是相关的,但似乎application和application2是独立的包——相对导入用于在同一个包中导入。)
最后,请确保始终将整个应用程序视为一个包,或者始终将每个应用程序视为它们自己的包。不要混搭。如果package/在路径中(例如sys.path包括package/),那么您确实可以执行“from package.application import foo”,但是如果您也执行“from application import foo”,Python可能没有意识到它们是同一件事——它们的名称不同,它们在不同的路径中——并最终加载它的两个不同副本,这是您绝对不想要的。最好始终使用相同的方式导入,例如,使用project.app.models
,因为否则,您可能会发现您的模块被导入两次,这有时会导致中讨论的模糊错误。如果深入研究django哲学,您会发现,项目是应用程序的集合。其中一些应用程序可能依赖于其他应用程序,这很好。然而,你一直想要的是让你的应用程序可以插入,这样你就可以将它们移动到另一个项目中,并在那里使用它们。要做到这一点,您需要剥离代码中与项目相关的所有内容,以便在进行导入时可以这样做
from aplication.file import test_method
这将是django的做法。格伦回答了为什么你会犯错误,所以我就不谈了。运行命令启动新项目时:django-admin.py startproject myproject
django-admin.py startproject myproject
这将创建一个文件夹,其中包含django需要的一堆文件、manage.py settings、py etc,但它将为您做另一件事。它将把文件夹“myproject”放在python路径上。简而言之,这意味着无论您将什么应用程序放在那个文件夹中,都可以像上面所示那样导入。您不需要使用django-admin.py来启动项目,因为没有什么神奇的事情发生,它只是一种快捷方式。所以你可以把你的应用程序文件夹放在任何地方真的,你只需要把它们放在python路径上,这样你就可以直接从它们导入,使你的代码项目独立,这样它就可以很容易地在任何未来的项目中使用,遵循django所基于的干式原则。请在其工作时和不工作时包含PYTHONPATH设置。唉,django本身通过将\uuuu init\uuuuuuuuu.py
文件放在项目目录中,并将项目目录放在sys.path上而将其搞糟。虽然总是省略项目名称是正确的做法,但对于Django来说,这仍然是一个丑陋的黑客行为(他们应该从项目目录中省略\uuuuuu init\uuuuuuuuuuuy
文件)