1141 Stimmen

Wie kann ich ein "Enum" in Python darstellen?

Ich bin hauptsächlich ein C#-Entwickler, aber ich arbeite derzeit an einem Projekt in Python.

Wie kann ich das Äquivalent einer Enum in Python darstellen?

84voto

Aaron Maenpaa Punkte 112919

Das Typesafe-Enum-Muster, das in Java vor JDK 5 verwendet wurde, hat eine eine Reihe von Vorteilen. Ähnlich wie in Alexandru's Antwort, erstellen Sie eine Klasse und die Felder auf Klassenebene sind die Enum-Werte; allerdings sind die Enum Werte sind jedoch Instanzen der Klasse und keine kleinen Ganzzahlen. Dies hat hat den Vorteil, dass die Enum-Werte nicht versehentlich mit kleinen mit kleinen Ganzzahlen vergleichen, Sie können kontrollieren, wie sie gedruckt werden, beliebige Methoden hinzufügen, wenn das nützlich ist, und mit isinstance Behauptungen aufstellen:

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

Eine aktuelle Thema auf python-dev wies darauf hin, dass es eine Reihe von Enum-Bibliotheken in freier Wildbahn gibt, darunter:

67voto

Zoetic Punkte 47

Eine Enum-Klasse kann ein Einzeiler sein.

class Enum(tuple): __getattr__ = tuple.index

Verwendung (Vorwärts- und Rückwärtssuche, Schlüssel, Werte, Elemente usw.)

>>> 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)]

56voto

royal Punkte 512

Ich stimme also zu. Wir sollten die Typsicherheit in Python nicht erzwingen, aber ich möchte mich vor dummen Fehlern schützen. Was denken wir also darüber?

class Animal(object):
    values = ['Horse','Dog','Cat']

    class __metaclass__(type):
        def __getattr__(self, name):
            return self.values.index(name)

Dadurch wird eine Wertkollision bei der Definition meiner Enums vermieden.

>>> Animal.Cat
2

Es gibt einen weiteren praktischen Vorteil: wirklich schnelle Rückwärtssuche:

def name_of(self, i):
    return self.values[i]

55voto

dF. Punkte 70587

Python hat kein eingebautes Äquivalent zu enum und andere Antworten enthalten Ideen für die Umsetzung Ihrer eigenen Ideen (vielleicht interessieren Sie sich auch für die überdrehte Version im Python-Kochbuch).

In Situationen jedoch, in denen ein enum in C gefordert werden würde, lande ich in der Regel bei nur mit einfachen Zeichenketten : Aufgrund der Art und Weise, wie Objekte/Attribute implementiert sind, ist (C)Python ohnehin darauf optimiert, sehr schnell mit kurzen Zeichenketten zu arbeiten, so dass die Verwendung von Ganzzahlen keinen wirklichen Leistungsvorteil bietet. Um sich vor Tippfehlern/ungültigen Werten zu schützen, können Sie an ausgewählten Stellen Prüfungen einfügen.

ANIMALS = ['cat', 'dog', 'python']

def take_for_a_walk(animal):
    assert animal in ANIMALS
    ...

(Ein Nachteil im Vergleich zur Verwendung einer Klasse ist, dass Sie den Vorteil der automatischen Vervollständigung verlieren)

43voto

Danilo Bargen Punkte 16995

Am 2013-05-10 stimmte Guido zu, die PEP 435 in die Standardbibliothek von Python 3.4 aufgenommen. Dies bedeutet, dass Python endlich eine eingebaute Unterstützung für Aufzählungen hat!

Es ist ein Backport für Python 3.3, 3.2, 3.1, 2.7, 2.6, 2.5 und 2.4 verfügbar. Er ist auf Pypi als enum34 .

Erklärung:

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

Vertretung:

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

Iteration:

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

Programmatischer Zugang:

>>> Color(1)
Color.red
>>> Color['blue']
Color.blue

Weitere Informationen finden Sie unter den Vorschlag . Eine offizielle Dokumentation wird wahrscheinlich bald folgen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X