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?

41voto

mbac32768 Punkte 11205

Ich ziehe es vor, Enums in Python wie folgt zu definieren:

class Animal:
  class Dog: pass
  class Cat: pass

x = Animal.Dog

Es ist fehlerfreier als die Verwendung von Ganzzahlen, da man sich nicht darum kümmern muss, dass die Ganzzahlen eindeutig sind (wenn man z. B. sagt, dass Hund = 1 und Katze = 1 ist, wäre man aufgeschmissen).

Es ist fehlerfreier als die Verwendung von Strings, da man sich keine Sorgen um Tippfehler machen muss (z.B. x == "catt" schlägt lautlos fehl, aber x == Animal.Catt ist eine Laufzeitausnahme).


ADDENDUM : Sie können diese Lösung noch verbessern, indem Sie Hund und Katze von einer Symbolklasse mit der richtigen Metaklasse erben lassen:

class SymbolClass(type):
    def __repr__(self): return self.__qualname__
    def __str__(self): return self.__name__

class Symbol(metaclass=SymbolClass): pass

class Animal:
    class Dog(Symbol): pass
    class Cat(Symbol): pass

Wenn Sie diese Werte dann z. B. für die Indexierung eines Wörterbuchs verwenden, werden sie bei der Abfrage ihrer Darstellung schön angezeigt:

>>> mydict = {Animal.Dog: 'Wan Wan', Animal.Cat: 'Nyaa'}
>>> mydict
{Animal.Dog: 'Wan Wan', Animal.Cat: 'Nyaa'}

36voto

user18695 Punkte 217
def M_add_class_attribs(attribs):
    def foo(name, bases, dict_):
        for v, k in attribs:
            dict_[k] = v
        return type(name, bases, dict_)
    return foo

def enum(*names):
    class Foo(object):
        __metaclass__ = M_add_class_attribs(enumerate(names))
        def __setattr__(self, name, value):  # this makes it read-only
            raise NotImplementedError
    return Foo()

Verwenden Sie es so:

Animal = enum('DOG', 'CAT')
Animal.DOG # returns 0
Animal.CAT # returns 1
Animal.DOG = 2 # raises NotImplementedError

wenn Sie nur eindeutige Symbole wollen und sich nicht um die Werte kümmern, ersetzen Sie diese Zeile:

__metaclass__ = M_add_class_attribs(enumerate(names))

damit:

__metaclass__ = M_add_class_attribs((object(), name) for name in names)

31voto

agf Punkte 159286

Eine weitere, sehr einfache Implementierung eines Enums in Python, die namedtuple :

from collections import namedtuple

def enum(*keys):
    return namedtuple('Enum', keys)(*keys)

MyEnum = enum('FOO', 'BAR', 'BAZ')

oder alternativ dazu,

# With sequential number values
def enum(*keys):
    return namedtuple('Enum', keys)(*range(len(keys)))

# From a dict / keyword args
def enum(**kwargs):
    return namedtuple('Enum', kwargs.keys())(*kwargs.values())

# Example for dictionary param:
values = {"Salad": 20, "Carrot": 99, "Tomato": "No i'm not"} 
Vegetables= enum(**values)

# >>> print(Vegetables.Tomato)        'No i'm not'

# Example for keyworded params: 
Fruits = enum(Apple="Steve Jobs", Peach=1, Banana=2)

# >>> print(Fruits.Apple)             'Steve Jobs'

Wie die obige Methode, die die Unterklassen set dies ermöglicht:

'FOO' in MyEnum
other = MyEnum.FOO
assert other == MyEnum.FOO

Sie ist jedoch flexibler, da sie verschiedene Schlüssel und Werte haben kann. Dies ermöglicht

MyEnum.FOO < MyEnum.BAR

so zu verhalten, wie es erwartet wird, wenn Sie die Version verwenden, die fortlaufende Zahlenwerte einträgt.

31voto

Saša Šijak Punkte 7956

Ab Python 3.4 gibt es eine offizielle Unterstützung für Enums. Sie können Dokumentation und Beispiele finden hier auf der Python 3.4 Dokumentationsseite .

Aufzählungen werden mit der Klassensyntax erstellt, wodurch sie leicht zu lesen und zu schreiben. Eine alternative Erstellungsmethode ist beschrieben in Funktionale API. Um eine Aufzählung zu definieren, untergliedern Sie die Klasse Enum wie folgt:

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

29voto

Halten Sie es einfach und verwenden Sie das alte Python 2.x (siehe unten für Python 3!):

class Enum(object): 
    def __init__(self, tupleList):
            self.tupleList = tupleList

    def __getattr__(self, name):
            return self.tupleList.index(name)

Dann:

DIRECTION = Enum(('UP', 'DOWN', 'LEFT', 'RIGHT'))
DIRECTION.DOWN
1

Halten Sie es einfach, wenn Sie Python 3 :

from enum import Enum
class MyEnum(Enum):
    UP = 1
    DOWN = 2
    LEFT = 3
    RIGHT = 4

Dann:

MyEnum.DOWN

Siehe: https://docs.python.org/3/library/enum.html

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