복붙노트

[PYTHON] 파이썬, 열거 형은 무엇에 좋은가요? [복제]

PYTHON

파이썬, 열거 형은 무엇에 좋은가요? [복제]

Python 3.4에서는 표준 라이브러리에 enum lib가 있습니다. enum. 우리는 Python 2.4에서 2.7 (그리고 심지어 3.1에서 3.3까지), pypi에서 enum34와 함께 작동하는 enum을위한 백 포트를 얻을 수 있습니다.

그러나 우리는이 새로운 모듈이 없으면 꽤 오랫동안 함께 할 수있었습니다. 그렇다면 왜 우리는 지금 그것을 가지고 있습니까?

다른 언어의 enum의 목적에 대한 일반적인 생각이 있습니다. 파이썬에서는 다음과 같이 맨손 클래스를 사용하고이를 열거 형으로 참조하는 것이 일반적입니다.

class Colors:
    blue = 1
    green = 2
    red = 3

이 값을 API에서 사용하여 값의 표준 표현을 만들 수 있습니다 (예 :

function_of_color(Colors.green)

이것이 어떤 비판을 가지고 있다면, 그것은 변경 가능합니다. 여러분은 그것을 반복 할 수 없으며 (쉽게) 정수의 의미를 어떻게 알 수 있습니까?

그렇다면 불변의 명명 된 튜플과 같은 것을 사용할 수 있을까요?

>>> Colors = namedtuple('Colors', 'blue green red')
>>> colors = Colors('blue', 'green', 'red')
>>> colors
Colors(blue='blue', green='green', red='red')
>>> list(colors)
['blue', 'green', 'red']
>>> len(colors)
3
>>> colors.blue
'blue'
>>> colors.index(colors.blue)
0

namedtuple의 생성은 다소 불필요합니다 (각 이름을 두 번 써야합니다). 그래서 다소 우아합니다. 색상의 "숫자"를 얻는 것도 조금 우아하지 않습니다 (색상을 두 번 써야합니다). 값 검사는 문자열로 수행되어야하는데, 이는 약간 덜 효율적입니다.

다시 열거 형으로.

열거 형의 목적은 무엇입니까? 언어에 대해 어떤 가치를 창출합니까? 언제 사용해야합니까? 언제 피할 수 있습니까?

해결법

  1. ==============================

    1.열거 형은 PEP 435를 통해 파이썬에 들어갔습니다. 주어진 이유는 다음과 같습니다.

    열거 형은 PEP 435를 통해 파이썬에 들어갔습니다. 주어진 이유는 다음과 같습니다.

    이 목적을 위해 숫자와 문자열을 사용하면 "마법의 숫자"또는 "마법의 문자열"로 특징 지을 수 있습니다. 숫자는 그 의미를 거의 가지고 있지 않으며 문자열은 쉽게 혼동됩니다 (대문자? 철자 또는 뱀 또는 낙타의 경우?).

    요일과 학교 문자 등급은 이러한 종류의 가치 수집의 예입니다.

    다음은 docs의 예제입니다.

    from enum import Enum
    
    class Color(Enum):
        red = 1
        green = 2
        blue = 3
    

    벌거 벗은 클래스와 마찬가지로 이것은 명명 된 튜플 예제보다 훨씬 읽기 쉽고 우아하며, 또한 불변이며 아래에서 보게 될 추가 이점이 있습니다.

    >>> type(Color.red)
    <enum 'Color'>
    >>> isinstance(Color.green, Color)
    True
    

    이를 통해 Enum 정의에서 멤버에 대한 기능을 정의 할 수 있습니다. 값에 대한 기능을 정의하는 것은 다른 이전 방법으로 수행 할 수 있지만 매우 유용하지는 않습니다.

    문자열 표현은 사람이 읽을 수있는 반면 repr은 더 많은 정보를 갖습니다.

    >>> print(Color.red)
    Color.red
    >>> print(repr(Color.red))
    <Color.red: 1>
    

    나는 이것을 마술 숫자보다 개선 된 것으로 생각하고 심지어 명명 된 튜플의 문자열보다 더 나은 것으로 생각한다.

    열거 형은 반복 (예 : 명명 된 튜플과 비슷하지만 맨손 클래스는 아님)도 지원합니다.

    >>> for color in Color:
            print(color)
    Color.red
    Color.green
    Color.blue
    

    __members__ 속성은 열거 형의 이름을 해당 열거 형 객체에 매핑하는 OrderedDict입니다 (namedtuple의 _asdict () 함수와 비슷 함).

    열거 형을 serialize하고 deserialize 할 수 있습니다 (누군가이 문제에 대해 걱정할 경우를 대비하여).

    >>> import pickle
    >>> color.red is pickle.loads(pickle.dumps(color.red))
    True
    

    이 기능은 베어 클래스에없는 멋진 기능이며, 명명 된 튜플에 별칭이 있음을 알리기가 어려울 수 있습니다.

    class Color(Enum):
        red = 1
        green = 2
        blue = 3
        really_blue = 3
    

    별칭은 정식 이름 뒤에옵니다. 그러나 둘 다 동일합니다.

    >>> Color.blue is Color.really_blue
    True
    

    값 충돌을 피하기 위해 별칭을 금지해야하는 경우 enum.unique 데코레이터 (엄격하게 지배적 인 기능)를 사용하십시오.

    열거 형은 프로세스에서 단일 객체의 ID에 대한 빠른 검사 인 is로 테스트하도록되어 있습니다.

    >>> Color.red is Color.red
    True
    >>> Color.red is Color.blue
    False
    >>> Color.red is not Color.blue
    True
    

    평등에 대한 테스트도 있지만, is와의 동일성 테스트는 최적입니다.

    Enum 클래스는 일반적인 Python 유형과는 다른 의미를가집니다. Enum의 값은 Enum의 인스턴스이며 해당 값에 대한 메모리의 싱글 톤입니다. 인스턴스화 할 다른 용도는 없습니다.

    >>> Color.red is Color('red')
    

    이것은 염두에 두는 것이 중요합니다. 아마도 그것은 단점입니다. 그러나이 차원에서 비교하는 것은 사과와 오렌지를 비교하는 것입니다.

    Enum 클래스는 멤버가 만들어지는 순서를 알고 있지만 열거 형은 순서가 있다고 가정하지 않습니다. 이것은 열거 될 수있는 많은 것들이 자연 순서가 없기 때문에 질서가 임의적 일 수 있기 때문에 기능입니다.

    그러나 열거 형을 지정할 수 있습니다 (다음 섹션 참조).

    선언 된 멤버를 사용하여 Enum의 하위 클래스를 만들 수는 없지만 멤버가 비헤이비어를 공유하도록 선언하지 않은 Enum의 하위 클래스를 만들 수 있습니다 (문서의 OrderedEnum 레서피 참조).

    이 기능은 Enum을 멤버로 서브 클래 싱하는 것은 거의 의미가 없지만 다시 비교는 사과와 오렌지입니다.

    이것은 파이썬에서 새로운 표준 열거입니다. 공동 작업자는 열거 형이 이러한 열거 형처럼 작동 할 것으로 기대합니다.

    임의의 데이터 대신 표준 이름을 사용하도록 명시 적으로 지정하려는 코드에서 열거 된 데이터의 표준 소스를 어디에서나 사용할 수 있습니다.

    예를 들어, 코드에서 사용자가 "녹색", "녹색", 2 또는 "녹색"이 아니라 Color.green이 아니라고 명시하고 싶다면 enum.Enum 객체를 사용하십시오. 그것은 명시 적이며 구체적입니다.

    설명서에는 많은 예제와 조리법이 있습니다.

    자신 만의 롤링을 중지하거나 사람들이 마법의 숫자와 문자열을 추측하게하십시오. 그들을 피하지 마십시오. 그들을 받아 들여라.

    그러나 열거 형 멤버가 역사적인 이유로 정수가되어야하는 경우 같은 모듈에서 동일한 동작을하는 IntEnum이 있지만 Enum을 서브 클래 싱하기 전에 기본 int를 하위 클래스에 포함하기 때문에 정수이기도합니다. IntEnum 도움말에서 :

    class IntEnum(builtins.int, Enum)
    

    IntEnum 값이 int의 인스턴스로 테스트되는지 확인할 수 있습니다.

  2. from https://stackoverflow.com/questions/37601644/python-whats-the-enum-type-good-for by cc-by-sa and MIT license