在 PYTHONPATH 设置为子目录的特殊情况下不理解 Python 模块

Mic*_*eur 5 python module python-import

我遇到了一个让我对 Python 模块感到困惑的问题。我构建了一个最小的工作示例:

\n
$ tree\n\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 configuration.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 error_code.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test.py\n
Run Code Online (Sandbox Code Playgroud)\n

应用程序/配置.py

\n
$ tree\n\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 configuration.py\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 error_code.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test.py\n
Run Code Online (Sandbox Code Playgroud)\n

应用程序/错误代码.py

\n
import enum\n\nclass ErrorCode(enum.Enum):\n    Success = 0\n    Error1 = 1\n
Run Code Online (Sandbox Code Playgroud)\n

测试.py

\n
#!/usr/bin/env python\n\nfrom app.configuration import Configuration\nfrom app.error_code import ErrorCode\n\nc = Configuration()\n\nprint(c.status())\nprint(c.status() == ErrorCode.Error1)\n
Run Code Online (Sandbox Code Playgroud)\n

命令:PYTHONPATH=app ./test.py

\n

输出:

\n
from error_code import ErrorCode\n\nclass Configuration:\n    def status(self):\n        return self._status\n\n    def __init__(self):\n        self._status = ErrorCode.Error1\n
Run Code Online (Sandbox Code Playgroud)\n

为什么在这种情况下输出显示ErrorCode.Error1False相等检查?

\n

我想这与模块有关,因为如果在 app/configuration.py 中我替换它,它就会from error_code import ErrorCodefrom app.error_code import ErrorCode预期工作。但这对我来说似乎很奇怪。

\n

我应该在哪里获取此特定行为的文档?

\n

jua*_*aga 2

test.py这是因为所在的目录被添加到导入路径中。这就是 test.py 中的导入开始起作用的原因:

from app.error_code import ErrorCode
Run Code Online (Sandbox Code Playgroud)

但是,当您这样做时:

from error_code import ErrorCode
Run Code Online (Sandbox Code Playgroud)

就在其中app/configuration.py依靠着PYTHONPATH=app/。但是原始导入被缓存为"app.error_code"sys.modules因此当您导入时error_code在缓存中找不到它,因为它需要作为 存在"error_code",并且它不被识别为同一个模块,因此它被重新导入为新模块。海事组织,你应该使用:

from app.error_code import ErrorCode
Run Code Online (Sandbox Code Playgroud)

正如您所指出的,导入将被适当缓存。实际上,它的父目录app应该首先添加到 PYTHONPATH 中。更好的是,您不应该依赖工作目录或PYTHONPATH,而只需使您的项目 pip 可安装即可。