导入的枚举类与自身比较不相等

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

在我的代码中,我对具有相同值但比较不相等的

Enum
实例感到困惑。我很快意识到他们的
id(...)
是不同的。后来,没那么快,我意识到自上次工作以来唯一的变化是
import
语句:使用显式模块路径而不是相对路径。

然后我想出了这个孤立的例子。

$ ls
e/

$ ls e
__init__.py  __pycache__/  m1.py  m1.pyc  m2.py

$  python3 --version
Python 3.5.1

$ cat e/m1.py
from enum import Enum
class E(Enum):
    x=0

$ cat e/m2.py
from m1 import E as E1
from e.m1 import E as E2

print(id(E1), id(E1.x))
print(id(E2), id(E2.x))

让我们运行一下:

$ PYTHONPATH=~/test python3 e/m2.py
41536520 42656096
41537464 42656488

显然,等式(通过

Enum
的恒等式)不成立。还有其他人觉得这很麻烦吗?

让我详细说明一下。添加另外两个文件:

$ cat e/file1.py
from m1 import E

class C():
    def __init__(self):
        self.x = E.x

还有一个。注意进口的差异。

$ cat e/file2.py
from e.m1 import E
from file1 import C

c = C()
print(c.x, E.x)
print('Surprise! ->', c.x is E.x)

两者都是有效的进口。现在运行它。

$ PYTHONPATH=~/test python3 e/file2.py
E.x E.x
Surprise! -> False

如何避免这个陷阱?我有理由不为此烦恼吗?

python python-3.x enums
3个回答
15
投票

后来,没那么快,我意识到自上次工作以来唯一的变化是

import
语句:使用显式模块路径而不是相对路径。

Python 3 没有隐式相对导入。您的“相对”导入实际上是另一个绝对导入。您正在导入两个完全不同的模块,

m1
e.m1
,它们恰好来自同一个文件。

如果你想在Python 3中使用相对导入,你需要明确说明:

from .m1 import E
#    ^ explicit relative import

如果您运行程序

python3 -m e.m2

您将避免允许

m1
e.m1
都存在的模块搜索路径问题。您还可以手动修复
sys.path
并从 __package__
 设置 
e/m2.py


8
投票

这不是

Enum
的问题,而是 python 导入的问题。 如果您使用不同的名称导入相同的模块,您将获得两个不同的模块。

尝试,例如,

E1 is E2


0
投票

如果您从不在您的主子目录中的其他目录导入python模块,则会导致与此主题相关的问题,我以这种方式解决:

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), './../coboljsonifier-library/src')))
from coboljsonifier.copybookextractor import CopybookExtractor

希望它对你有用!

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