try/catch를 사용하지 않고 Python Enum에 int 값이 있는지 테스트하려면 어떻게 해야 합니까?
Python Enum 클래스를 사용하여 try/catch를 사용하지 않고 Enum에 특정 int 값이 포함되어 있는지 테스트할 수 있는 방법이 있습니까?
다음 클래스와 함께:
from enum import Enum
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
값 6(참 반환) 또는 값 7(거짓 반환)을 테스트하려면 어떻게 해야 합니까?
값 검정
변종 1
로 삼다Enum라는 멤버가 있습니다._value2member_map_(문서화되지 않았으며 향후 파이썬 버전에서 변경/수정될 수 있음):
print(Fruit._value2member_map_)
# {4: <Fruit.Apple: 4>, 5: <Fruit.Orange: 5>, 6: <Fruit.Pear: 6>}
당신은 당신의 안에 값이 있는지 테스트할 수 있습니다.Enum지도에 설명합니다.
5 in Fruit._value2member_map_ # True
7 in Fruit._value2member_map_ # False
변종 2
이 기능을 사용하지 않으려면 이 방법을 사용할 수 있습니다.
values = [item.value for item in Fruit] # [4, 5, 6]
더 나은 편 (으)로: 용사합다니편을 합니다.set그자리의 in연산자가 더 효율적일 것입니다.
values = set(item.value for item in Fruit) # {4, 5, 6}
으로 테스트합니다.
5 in values # True
7 in values # False
더하다has_value의
그런 다음 클래스에 메소드로 추가할 수 있습니다.
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
@classmethod
def has_value(cls, value):
return value in cls._value2member_map_
print(Fruit.has_value(5)) # True
print(Fruit.has_value(7)) # False
python 3.9 (?) python 오퍼에서 시작하여 다음을 수행할 수 있습니다.
from enum import IntEnum
class Fruit(IntEnum):
Apple = 4
Orange = 5
Pear = 6
print(6 in iter(Fruit)) # True
로 " 을음생필없습다니요가할성"를 .list되풀이하여.iter(Fruit)그러면 됩니다. 반복적으로 필요한 경우 위와 같이 집합을 생성할 가치가 있을 수 있습니다.
values = set(Fruit)
print(5 in values) # True
키 테스트
이 아닌) , 는 만약당값이신테이싶것다나입니사다용할는름고면하아를 사용할 입니다._member_names_:
'Apple' in Fruit._member_names_ # True
'Mango' in Fruit._member_names_ # False
모든 열거형이 항목이 있는지 확인할 수 있도록 하는 방법이 있습니다.
import enum
class MyEnumMeta(enum.EnumMeta):
def __contains__(cls, item):
return isinstance(item, cls) or item in [v.value for v in cls.__members__.values()]
class MyEnum(enum.Enum, metaclass=MyEnumMeta):
FOO = "foo"
BAR = "bar"
이제 쉽게 확인할 수 있습니다.
>>> "foo" in MyEnum
True
모든 열거형의 값이 항상 동일한 유형(예: 문자열)인 경우에도 더 단순해질 수 있습니다.
import enum
class MyEnumMeta(enum.EnumMeta):
def __contains__(cls, item):
return item in cls.__members__.values()
class MyEnum(str, enum.Enum, metaclass=MyEnumMeta):
FOO = "foo"
BAR = "bar"
편집: @MestreLion의 코멘트에 따라, 저는 첫 번째 예를 포함하도록 업데이트했습니다.isinstance확인합니다. 확인하지 않으면 이미 인스턴스화된 열거형 값을 확인하는 경우 테스트가 실패합니다.
편집: 또 다른 버전, 기술적으로 가장 정확한 버전:
import enum
class MyEnumMeta(enum.EnumMeta):
def __contains__(cls, item):
try:
cls(item)
except ValueError:
return False
else:
return True
class MyEnum(enum.Enum, metaclass=MyEnumMeta):
FOO = "foo"
BAR = "bar"
사용할 수 있습니다.Enum.__members__이름을 멤버에 매핑하는 순서 사전:
In [12]: 'Apple' in Fruit.__members__
Out[12]: True
In [13]: 'Grape' in Fruit.__members__
Out[13]: False
열거형에 구성원이 많은 경우 새 목록을 만들지 않고 지정된 값이 발견될 때 열거형 보행을 중지하므로 이 접근 방식이 더 빠를 수 있습니다.
any(x.value == 5 for x in Fruit) # True
any(x.value == 7 for x in Fruit) # False
Reda Maachi가 시작한 것을 기반으로 합니다.
6 in Fruit.__members__.values()
True를 반환합니다.
7 in Fruit.__members__.values()
False를 반환합니다.
IntEnum을 목록으로 변환하여 정상적으로 테스트합니다.
from enum import IntEnum
class Foo(IntEnum):
ONE = 1
TWO = 2
THREE = 3
print(1 in list(Foo))
True
print(4 in list(Foo))
False
from enum import Enum
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
@staticmethod
def has_value(item):
return item in [v.value for v in Fruit.__members__.values()]
원래는 하지 마.
Enum을 사용하는 경우 다음을 사용하여 Enum을 테스트할 수 있습니다.
if isinstance(key, Fruit):
하지만 그렇지 않다면, 시도해 보세요.열거형을 테스트하는 파이썬적인 방법입니다.사실, 오리 유형화 패러다임의 어떤 휴식에도 불구하고.
IntEnum에서 int를 테스트하는 정확하고 피톤적인 방법은 시도해보고 실패했을 때 ValueError를 잡는 것입니다.
위에서 제안된 솔루션 중 많은 수가 적극적으로 사용되지 않으며 3.8에서 허용되지 않습니다("DecrecationWarning: 격납 검사에서 열거형이 아닌 것을 사용하면 Python 3.8에서 TypeError가 발생합니다").
Python 3.8에서 – 목록에 강제로 포함시킵니다.
3.8 정도 이후에는 다음과 같이 열거형을 강제로 목록에 넣어 테스트할 수 있습니다(IntEnum 사용).
from enum import IntEnum
class Fruit(IntEnum):
Kiwi = 2
Apple = 4
Orange = 5
Pear = 6
for x in range(8):
print(f'{x}, {x in list(Fruit)}')
다음과 같이 인쇄됩니다.
0, False
1, False
2, True
3, False
4, True
5, True
6, True
7, False
안에 있는지만 확인하세요.Enum. _value2member_map_
In[15]: Fruit._value2member_map_
Out[15]: {4: <Fruit.Apple: 4>, 5: <Fruit.Orange: 5>, 6: <Fruit.Pear: 6>}
In[16]: 6 in Fruit._value2member_map_
Out[16]: True
In[17]: 7 in Fruit._value2member_map_
Out[17]: False
EAFP 버전의 답변:
try:
Fruit(val)
return True
except ValueError:
return False
아직 아무도 언급하지 않은 라이너 솔루션이 하나 더 있습니다.
is_value_in_fruit = any(f.value == value_to_check for f in Fruit)
또한, 만약 당신이IntEnum대신에Enum, (class Fruit(IntEnum)) 이렇게 하면 됩니다.
is_value_in_fruit = any(f == value_to_check for f in Fruit)
이건 어때?
from enum import Enum
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
has_apples = 4 in [n.value for n in Fruit]
이렇게 하면 다음 작업도 수행할 수 있습니다.
has_apples = "Apple" in [n.name for n in Fruit]
IntEnum+__members__
사용할 수 있습니다.IntEnum그리고.__members__필요한 행동을 달성하기 위해:
from enum import IntEnum
class Fruit(IntEnum):
Apple = 4
Orange = 5
Pear = 6
>>> 6 in Fruit.__members__.values()
True
>>> 7 in Fruit.__members__.values()
False
Enum목록 이해 +.value
계속해야 하는 경우Enum할 수 있는 일:
>>> 6 in [f.value for f in Fruit]
True
>>> 7 in [f.value for f in Fruit]
False
EAPF +ValueError
또는 허가 방법보다 용서를 구하기 쉬운 방법을 사용할 수 있습니다.
try:
Fruit(x)
except ValueError:
return False
else:
return True
이를 위한 가장 깨끗하고 친숙한 방법은try/except:
class Fruit(Enum):
Apple = 4
Orange = 5
Pear = 6
# If you want it in function form
def is_fruit(x):
try:
Fruit(x)
except ValueError:
return False
else:
return True
class MyEnumMixin:
raw_values = None # for IDE autocomplete
def __new__(cls, value):
if 'raw_values' not in cls.__dict__:
cls.raw_values = set()
cls.raw_values.add(value)
if cls.__bases__[0] is MyEnumMixin:
member = object().__new__(cls)
else:
member = super().__new__(cls, value)
member._value_ = value
return member
class MyEnum(MyEnumMixin, Enum):
FOO = 1
BAR = 'bar'
print(1 in MyEnum.raw_values)
print('bar' in MyEnum.raw_values)
class MyStrEnumMixin(MyEnumMixin, str):
pass
class MyStrEnum(MyStrEnumMixin, Enum):
FOO = 'foo'
BAR = 'bar'
print('foo' in MyStrEnum.raw_values)
print('bar' in MyStrEnum.raw_values)
언급URL : https://stackoverflow.com/questions/43634618/how-do-i-test-if-int-value-exists-in-python-enum-without-using-try-catch
'programing' 카테고리의 다른 글
| 워드프레스에 로그인한 사용자 목록? (0) | 2023.07.18 |
|---|---|
| Firestore에서 json 내보내기 (0) | 2023.07.18 |
| SQLAlchemy ORM을 사용하여 데이터베이스를 효율적으로 업데이트 (0) | 2023.07.18 |
| 왜 그들은 px대신에? (0) | 2023.07.18 |
| 그룹화된 다중 막대 그림 표시 방법 (0) | 2023.07.18 |