8

これは、Python Enums のミュータブルな値が同じオブジェクトである理由の続きです。.

an の値Enumが変更可能な場合 ( lists など)、それらの値はいつでも変更できます。Enumメンバーが値によって取得される場合、特に誰かがうっかりして検索した値を変更した場合、これは問題を引き起こすと思いますEnum

>>> from enum import Enum
>>> class Color(Enum):
        black = [1,2]
        blue = [1,2,3]

>>> val_1 = [1,2]
>>> val_2 = [1,2,3]

>>> Color(val_1)
<Color.black: [1, 2]>

>>> Color(val_2)
<Color.blue: [1, 2, 3]>

>>> my_color = Color(val_1)
>>> my_color.value.append(3)

>>> Color(val_2)
<Color.black: [1, 2, 3]>

>>> Color(val_1)
Traceback (most recent call last):
  ...
ValueError: [1, 2] is not a valid Color

Python の通常のイディオムを考えると、これは問題ないと思います。これは、ユーザーがミュータブルを値として使用できることを意味します開いEnumている可能性のあるワームの缶を理解するためだけです。

ただし、これにより 2 番目の問題が発生します。メンバーを値で検索でき、値が可変である可能性があるためEnum、ハッシュマップ/ 以外の方法で検索を行う必要があります。dictkeydict

値によるルックEnumアップをdict?

4

2 に答える 2

6

私の 2 番目の質問に対する答えは、enum.py.

それぞれには、ハッシュ可能な (つまり、不変の) 値のペアEnum 含まれており、 by 値を検索すると、その からメンバーを取得しようとします。値がhashableでない場合は、すべての既存の値と等しいかどうか総当たりで比較し、一致が見つかった場合はメンバーを返します。関連するコードは、次の 468 ~ 476 行にあります。dictvalue->memberEnumdictEnumenum.py

try:
    if value in cls._value2member_map_:
        return cls._value2member_map_[value]
except TypeError:
    # not there, now do long search -- O(n) behavior
    for member in cls._member_map_.values():
        if member._value_ == value:
            return member
raise ValueError("%r is not a valid %s" % (value, cls.__name__))

そのため、 の設計者は、値で s をenum.py取得するときにすばやくルックアップしたいと考えていたように見えますEnumが、値に対して変更可能な値を持つ柔軟性を提供したいと考えていました(誰かがそれを望む理由はまだ考えられませんが)Enum。そもそも)。

于 2016-11-17T15:08:11.220 に答える