Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python(/Django)中强制使用不一致的文件导入路径_Python_Django_Import_Path - Fatal编程技术网

在Python(/Django)中强制使用不一致的文件导入路径

在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

我最近在Django(Python)中的导入遇到了一些问题。。。最好使用文件关系图进行解释:

- 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
文件)