programing

Python의 문자열 기반 열거형

kakaobank 2023. 5. 7. 11:47
반응형

Python의 문자열 기반 열거형

사용 중인 상태 목록을 캡슐화하려면 다음과 같이 하십시오.enum모듈:

from enum import Enum

class MyEnum(Enum):
    state1='state1'
    state2 = 'state2'

state = MyEnum.state1
MyEnum['state1'] == state  # here it works
'state1' == state  # here it does not throw but returns False (fail!)

그러나 문제는 다음과 같은 스크립트의 여러 컨텍스트에서 값을 문자열로 원활하게 사용해야 한다는 것입니다.

select_query1 = select(...).where(Process.status == str(MyEnum.state1))  # works but ugly

select_query2 = select(...).where(Process.status == MyEnum.state1)  # throws exeption

추가 형식 변환 호출을 피하는 방법 (str(state)위) 또는 기본값(state.value)?

로부터 물려받기에 충분해 보입니다.str과 같은 수업Enum:

from enum import Enum

class MyEnum(str, Enum):
    state1 = 'state1'
    state2 = 'state2'

까다로운 부분은 상속 체인의 클래스 순서가 다음과 같이 중요하다는 입니다.

class MyEnum(Enum, str):
    state1 = 'state1'
    state2 = 'state2'

던지기:

TypeError: new enumerations should be created as `EnumName([mixin_type, ...] [data_type,] enum_type)`

올바른 클래스를 사용하여 다음 작업을 수행합니다.MyEnum괜찮습니다.

print('This is the state value: ' + state)

참고로, 특별한 상속 트릭은 형식화된 문자열에 대해서도 필요하지 않은 것 같습니다.Enum상속만:

msg = f'This is the state value: {state}'  # works without inheriting from str

설명서(즉, 이전 버전의 Python을 사용하기 때문에 시도하지 않았지만 문서를 신뢰함)를 읽으면 Python 3.11 이후 다음을 수행할 수 있습니다.

from enum import StrEnum

class Directions(StrEnum):
    NORTH = 'north',    # notice the trailing comma
    SOUTH = 'south'

print(Directions.NORTH)
>>> north

자세한 내용은 문서설계 토론을 참조하시기 바랍니다.

python 3.6+실행하고 있다면,pip install StrEnum다음을 수행할 수 있습니다(제가 선택했습니다).

from strenum import StrEnum

class URLs(StrEnum):
    GOOGLE = 'www.google.com'
    STACKOVERFLOW = 'www.stackoverflow.com'

print(URLs.STACKOVERFLOW)

>>> www.stackoverflow.com

당신은 여기에서 그것에 대해 더 읽을 수 있습니다.


Also, this was mentioned in the docs - how to create your own enums based on other classes:

IntEnum은 열거형 모듈의 일부이지만 독립적으로 구현하는 것은 매우 간단합니다.

클래스 IntEnum(int, Enum): pass 유사한 파생 열거를 정의할 수 있는 방법을 보여줍니다. 예를 들어 int 대신 str에 혼합하는 StrEnum입니다.

일부 규칙:

Enum을 하위 분류할 때 혼합 형식은 위의 IntEnum 예제에서와 같이 기본 순서에서 Enum 자체 앞에 나타나야 합니다.

Enum은 모든 유형의 멤버를 가질 수 있지만 추가 유형을 혼합한 후에는 모든 멤버가 위의 int와 같은 해당 유형의 값을 가져야 합니다.이 제한은 메소드만 추가하고 다른 유형은 지정하지 않는 믹스인에는 적용되지 않습니다.

다른 데이터 유형이 혼합된 경우 값 특성은 동일하고 비교가 동일하지만 열거 멤버 자체와 동일하지 않습니다.

%-style 형식 지정: %s 및 %r은 각각 Enum 클래스의 str() 및 repr()을 호출합니다. 다른 코드(예: IntEnum의 경우 %i 또는 %h)는 열거 멤버를 혼합 형식으로 처리합니다.

형식이 지정된 문자열 리터럴, str.format() 및 format()은 하위 클래스에서 str() 또는 format()을 재정의하지 않는 한 혼합 형식 형식의 형식()을 사용합니다. 이 경우 재정의된 메서드 또는 Enum 메서드가 사용됩니다.!s 및 !r 형식 코드를 사용하여 Enum 클래스의 str() 및 repr() 메서드를 강제로 사용합니다.

출처: https://docs.python.org/3/library/enum.html#others

값을 사용하는 것이 무엇이 잘못되었습니까?

Python 을 사용하지 한 는 임, StrEnum 과 3.11을 파이썬 나, ▁the▁override▁im▁3▁just임,호를 재정의합니다.__str__(self)메서드가 올바른 Enum 클래스에 있습니다.

class MyStrEnum(str, Enum):

    OK     = 'OK'
    FAILED = 'FAILED'

    def __str__(self) -> str:
        return self.value

베스트

수업시간에 사이에 섞이는 동안.str그리고.Enum이 문제를 해결할 수 있습니다. 또한 작업에 적합한 도구를 얻는 것에 대해 항상 생각해야 합니다.

또한 올바른 도구가 문자열 값을 가진 MODULE_CONSTANT일 수도 있습니다.를 들면, 들면를예,loggingDEBUG, INFO 등과 같은 의미 있는 값을 가진 몇 개의 상수가 있습니다.int이 경우 s.

열거형은 좋은 도구이고 저는 종종 그것들을 사용합니다.그러나 기본적으로 동일한 Enum의 다른 멤버와 비교하기 위한 것이므로 문자열과 비교하려면 추가 후프를 통과해야 합니다.

이면 연된문자값유효한 Python 이용열사거멤음다있버를 사용하여 열거 수 ..name다음과 같은 속성:

from enum import Enum
class MyEnum(Enum):
    state1=0
    state2=1

print (MyEnum.state1.name)  # 'state1'

a = MyEnum.state1
print(a.name)  # 'state1'

연결된 문자열 값이 임의 문자열인 경우 다음을 수행할 수 있습니다.

class ModelNames(str, Enum):
    gpt2 = 'gpt2'
    distilgpt2 = 'distilgpt2'
    gpt2_xl = 'gpt2-XL'
    gpt2_large = 'gpt2-large'

print(ModelNames.gpt2) # 'ModelNames.gpt2'
print(ModelNames.gpt2 is str) # False
print(ModelNames.gpt2_xl.name) # 'gpt2_xl'
print(ModelNames.gpt2_xl.value) # 'gpt2-XL'

온라인으로 시도해 보십시오. https://repl.it/ @sytelus/sysstrest

와 함께auto:

from enum import Enum, auto

class AutoStrEnum(str, Enum):
    """
    StrEnum where auto() returns the field name.
    See https://docs.python.org/3.9/library/enum.html#using-automatic-values
    """
    @staticmethod
    def _generate_next_value_(name: str, start: int, count: int, last_values: list) -> str:
        return name

class MyEnum(AutoStrEnum):
    STATE_1 = auto()
    STATE_2 = auto()

사용해 보십시오.

MyEnum.STATE_1 == "STATE_1"  # True

문자열을 직접 사용하려면 다음을 사용하는 것을 고려할 수 있습니다.

MyEnum = collections.namedtuple(
    "MyEnum", ["state1", "state2"]
)(
    state1="state1", 
    state2="state2"
)

열거하기는커녕 오히려이 작업을 반복하거나 수행하는 중MyEnum.state1문자열 값을 직접 제공합니다.동일한 문 내에 명명된 튜플을 작성하면 하나만 있을 수 있습니다.

분명히 Enum을 사용하지 않는 것에 대한 트레이드오프가 있기 때문에 무엇을 더 중요하게 생각하느냐에 따라 달라집니다.

.value를 사용하면 됩니다.

MyEnum.state1.value == 'state1'
# True

언급URL : https://stackoverflow.com/questions/58608361/string-based-enum-in-python

반응형