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

问题描述 投票:0回答:1

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

$ tree

├── app
│   ├── configuration.py
│   ├── error_code.py
└── test.py

应用程序/配置.py

from error_code import ErrorCode

class Configuration:
    def status(self):
        return self._status

    def __init__(self):
        self._status = ErrorCode.Error1

应用程序/error_code.py

import enum

class ErrorCode(enum.Enum):
    Success = 0
    Error1 = 1

测试.py

#!/usr/bin/env python

from app.configuration import Configuration
from app.error_code import ErrorCode

c = Configuration()

print(c.status())
print(c.status() == ErrorCode.Error1)

命令:

PYTHONPATH=app ./test.py

输出:

ErrorCode.Error1
False

为什么在这种情况下,输出显示

ErrorCode.Error1
,而对于相等检查则显示
False

我想这与模块有关,因为如果在 app/configuration.py 中我将

from error_code import ErrorCode
替换为
from app.error_code import ErrorCode
,它会按预期工作。但我觉得很奇怪。

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

python module python-import
1个回答
1
投票

这是因为

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

from app.error_code import ErrorCode

但是,当你这样做时:

from error_code import ErrorCode

app/configuration.py
中它依赖于
PYTHONPATH=app/
。但是原始导入在
"app.error_code"
中缓存为
sys.modules
,因此当您导入
error_code
时,在缓存中找不到它,因为它需要以
"error_code"
的形式存在,并且不会被识别为相同的模块,因此它被重新导入为新模块。 IMO,你应该使用:

from app.error_code import ErrorCode

正如您所指出的,导入将被适当缓存。实际上,它是

app
的父目录,应该首先添加到 PYTHONPATH 中。更好的是,您不应该依赖工作目录或
PYTHONPATH
,而只需让您的项目 pip 可安装即可。

© www.soinside.com 2019 - 2024. All rights reserved.