저는 주로 C # 개발자이지만 현재 Python 프로젝트를 진행하고 있습니다.
파이썬에서 Enum과 동등한 것을 어떻게 나타낼 수 있습니까?
답변
PEP 435에 설명 된대로 열거 형이 Python 3.4에 추가되었습니다 . 또한 pypi 에서 3.3, 3.2, 3.1, 2.7, 2.6, 2.5 및 2.4 로 백 포트 되었습니다 .
고급 Enum 기술을 사용하려면 aenum 라이브러리 (2.7, 3.3 이상,.와 동일한 작성자)를 사용해보십시오 enum34
. 코드는 py2와 py3 사이에서 완벽하게 호환되지 않습니다 (예 : __order__
python 2에 필요 ).
- 사용하려면
enum34
수행$ pip install enum34
- 사용하려면
aenum
수행$ pip install aenum
설치 enum
(아무 번호는) 완전히 다른 호환되지 않는 버전을 설치하지 않습니다.
from enum import Enum # for enum34, or the stdlib version
# from aenum import Enum # for the aenum version
Animal = Enum('Animal', 'ant bee cat dog')
Animal.ant # returns <Animal.ant: 1>
Animal['ant'] # returns <Animal.ant: 1> (string lookup)
Animal.ant.name # returns 'ant' (inverse lookup)
또는 동등하게 :
class Animal(Enum):
ant = 1
bee = 2
cat = 3
dog = 4
이전 버전에서 열거 형을 달성하는 한 가지 방법은 다음과 같습니다.
def enum(**enums):
return type('Enum', (), enums)
다음과 같이 사용됩니다.
>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'
다음과 같은 방법으로 자동 열거를 쉽게 지원할 수도 있습니다.
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
다음과 같이 사용됩니다.
>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1
값을 다시 이름으로 변환하는 지원은 다음과 같이 추가 할 수 있습니다.
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
reverse = dict((value, key) for key, value in enums.iteritems())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)
이것은 해당 이름을 가진 모든 것을 덮어 쓰지만, 열거 형을 출력으로 렌더링하는 데 유용합니다. 역 매핑이 존재하지 않으면 KeyError가 발생합니다. 첫 번째 예를 들면 다음과 같습니다.
>>> Numbers.reverse_mapping['three']
'THREE'
답변
PEP 435 이전에는 Python에는 동등한 기능이 없었지만 직접 구현할 수있었습니다.
나 자신, 나는 이것을 간단하게 유지하는 것을 좋아한다.
class Animal:
DOG = 1
CAT = 2
x = Animal.DOG
Python 3.4 ( PEP 435 )에서 Enum 을 기본 클래스로 만들 수 있습니다 . 이것은 PEP에 설명 된 약간의 추가 기능을 제공합니다. 예를 들어 열거 형 멤버는 정수와 구별되며 a name
와 a 로 구성 value
됩니다.
class Animal(Enum):
DOG = 1
CAT = 2
print(Animal.DOG)
# <Animal.DOG: 1>
print(Animal.DOG.value)
# 1
print(Animal.DOG.name)
# "DOG"
값을 입력하지 않으려면 다음 바로 가기를 사용하십시오.
class Animal(Enum):
DOG, CAT = range(2)
Enum
구현 은리스트로 변환 될 수 있고 반복 가능하다 . 멤버의 순서는 선언 순서이며 값과 관련이 없습니다. 예를 들면 다음과 같습니다.
class Animal(Enum):
DOG = 1
CAT = 2
COW = 0
list(Animal)
# [<Animal.DOG: 1>, <Animal.CAT: 2>, <Animal.COW: 0>]
[animal.value for animal in Animal]
# [1, 2, 0]
Animal.CAT in Animal
# True
답변
다음은 하나의 구현입니다.
class Enum(set):
def __getattr__(self, name):
if name in self:
return name
raise AttributeError
사용법은 다음과 같습니다.
Animals = Enum(["DOG", "CAT", "HORSE"])
print(Animals.DOG)
답변
숫자 값이 필요한 경우 가장 빠른 방법은 다음과 같습니다.
dog, cat, rabbit = range(3)
Python 3.x에서는 끝에 별표 표시된 자리 표시자를 추가 할 수 있습니다. 메모리를 낭비하지 않고 계산할 수없는 경우 나머지 범위 값을 모두 흡수합니다.
dog, cat, rabbit, horse, *_ = range(100)
답변
당신을위한 최선의 해결책은 당신이 가짜 에서 요구하는 것에 달려 있습니다 enum
.
간단한 열거 형 :
다른 항목을 식별하는 이름enum
목록 만 필요한 경우 Mark Harrison 의 솔루션 (위)이 훌륭합니다.
Pen, Pencil, Eraser = range(0, 3)
를 사용하면 시작 값range
을 설정할 수 있습니다 .
Pen, Pencil, Eraser = range(9, 12)
위의 항목 외에도 항목이 일종의 컨테이너 에 속 해야하는 경우 클래스에 포함하십시오.
class Stationery:
Pen, Pencil, Eraser = range(0, 3)
열거 형 항목을 사용하려면 컨테이너 이름과 항목 이름을 사용해야합니다.
stype = Stationery.Pen
복잡한 열거 형 :
열거 형의 열거 목록이나 열거 형의보다 복잡한 사용의 경우 이러한 솔루션으로는 충분하지 않습니다. Python Cookbook에 게시 된 Python 에서 열거 시뮬레이션을 위한 Will Ware의 레시피를 확인할 수 있습니다. 온라인 버전은 여기에서 구할 수 있습니다 .
더 많은 정보:
PEP 354 : Python의 열거에는 Python의 열거에 대한 흥미로운 제안과 거부 이유가 있습니다.
답변
Java JDK 5 이전에 사용 된 typesafe 열거 형 패턴에는 여러 가지 장점이 있습니다. Alexandru의 답변과 마찬가지로 클래스를 만들고 클래스 수준 필드는 열거 형 값입니다. 그러나 열거 형 값은 작은 정수가 아닌 클래스의 인스턴스입니다. 이것은 열거 형 값이 실수로 작은 정수와 동등하게 비교되지 않는다는 이점이 있습니다. 인쇄 방법을 제어하고, 유용한 경우 임의의 방법을 추가하고 isinstance를 사용하여 어설 션을 만들 수 있습니다.
class Animal:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def __repr__(self):
return "<Animal: %s>" % self
Animal.DOG = Animal("dog")
Animal.CAT = Animal("cat")
>>> x = Animal.DOG
>>> x
<Animal: dog>
>>> x == 1
False
python-dev 의 최근 스레드는 다음을 포함하여 야생에 두 개의 열거 형 라이브러리가 있다고 지적했습니다.
- flufl.enum
- lazr.enum
- … 상상적으로 명명 된 열거 형
답변
Enum 클래스는 하나의 라이너가 될 수 있습니다.
class Enum(tuple): __getattr__ = tuple.index
사용 방법 (정방향 및 역방향 조회, 키, 값, 항목 등)
>>> State = Enum(['Unclaimed', 'Claimed'])
>>> State.Claimed
1
>>> State[1]
'Claimed'
>>> State
('Unclaimed', 'Claimed')
>>> range(len(State))
[0, 1]
>>> [(k, State[k]) for k in range(len(State))]
[(0, 'Unclaimed'), (1, 'Claimed')]
>>> [(k, getattr(State, k)) for k in State]
[('Unclaimed', 0), ('Claimed', 1)]