Wie soll ich am besten emulieren und / oder Enum ist in Python vermeiden? [Duplikat]

StackOverflow https://stackoverflow.com/questions/108523

  •  01-07-2019
  •  | 
  •  

Frage

    

Diese Frage bereits eine Antwort hier:

         

Ich habe eine kleine Klasse unter Verwendung von Aufzählungen in einigen Python-Projekten zu emulieren. Gibt es einen besseren Weg, oder macht dies die am meisten Sinn für einige Situationen?

Klasse Code hier:

class Enum(object):
'''Simple Enum Class
Example Usage:
>>> codes = Enum('FOO BAR BAZ') # codes.BAZ will be 2 and so on ...'''
def __init__(self, names):
    for number, name in enumerate(names.split()):
        setattr(self, name, number)
War es hilfreich?

Lösung

Es gibt viele gute Diskussion hier .

Andere Tipps

Aufzählungen sind für die Aufnahme in die Sprache vorgeschlagen vor, wurden aber abgelehnt (siehe http://www.python.org/dev/peps/pep-0354/ ), obwohl es bestehende Pakete könnten Sie stattdessen Ihre eigene Implementierung des Schreibens:

Die häufigste Enum Fall Werte aufgezählt, die Teil eines Staates oder Strategie-Entwurfsmuster sind. Die Aufzählungen sind bestimmte Zustände oder bestimmte optionale Strategien eingesetzt werden. In diesem Fall sind sie fast immer ein wesentlicher Bestandteil von einiger Klassendefinition

class DoTheNeedful( object ):
    ONE_CHOICE = 1
    ANOTHER_CHOICE = 2 
    YET_ANOTHER = 99
    def __init__( self, aSelection ):
        assert aSelection in ( self.ONE_CHOICE, self.ANOTHER_CHOICE, self.YET_ANOTHER )
        self.selection= aSelection

Dann wird in einem Client dieser Klasse.

dtn = DoTheNeeful( DoTheNeeful.ONE_CHOICE )

Was ich öfter sehen, ist dies in der Top-Level-Modul Kontext:

FOO_BAR = 'FOO_BAR'
FOO_BAZ = 'FOO_BAZ'
FOO_QUX = 'FOO_QUX'

... und später ...

if something is FOO_BAR: pass # do something here
elif something is FOO_BAZ: pass # do something else
elif something is FOO_QUX: pass # do something else
else: raise Exception('Invalid value for something')
Hinweis

, dass die Verwendung von is statt == ein Risiko hier eingeht - es wird davon ausgegangen, dass die Leute your_module.FOO_BAR anstatt die Zeichenfolge 'FOO_BAR' verwenden (was normal so interniert werden, dass is wird übereinstimmen, aber das kann sicherlich nicht auf) gezählt werden, und so kann nicht sinnvoll sein, je nach Kontext.

Ein Vorteil es auf diese Weise zu tun, ist, dass durch zu dieser Zeichenfolge überall eine Referenz suchen, die gespeichert wird, ist es sofort klar, woher er kam; FOO_BAZ ist viel weniger zweideutig als 2.

Abgesehen davon, die andere Sache, die meine Pythonic Empfindlichkeiten re der Klasse kränkt Sie vorschlagen, ist die Verwendung von split(). Warum passiert nicht nur in einem Tupel, Liste oder andere zählbare zu beginnen?

Der eingebaute Weg Aufzählungen zu tun ist:

(FOO, BAR, BAZ) = range(3)

, die für kleine Mengen gut funktioniert, hat aber einige Nachteile:

  • Sie müssen die Anzahl der Elemente von Hand zählen
  • Sie können nicht überspringen Werte
  • , wenn Sie einen Namen hinzufügen, müssen Sie auch den Bereich Nummer
  • aktualisieren

Für eine vollständige Enumeration Implementierung in Python finden Sie unter: http://code.activestate.com/recipes/67107/

Ich begann mit etwas, das viel wie S.Lott Antwort aussieht, aber ich nur ‚str‘ und ‚eq‘ (anstelle der gesamten Objektklasse) überlastete und so konnte ich den Aufzählungswert drucken und vergleichen.

class enumSeason():
    Spring = 0
    Summer = 1
    Fall = 2
    Winter = 3
    def __init__(self, Type):
        self.value = Type
    def __str__(self):
        if self.value == enumSeason.Spring:
            return 'Spring'
        if self.value == enumSeason.Summer:
            return 'Summer'
        if self.value == enumSeason.Fall:
            return 'Fall'
        if self.value == enumSeason.Winter:
            return 'Winter'
    def __eq__(self,y):
        return self.value==y.value

Drucken (x) wird den Namen anstelle des Wertes ergeben und zwei Werte Federhalte einander gleich sein wird.

   >>> x = enumSeason(enumSeason.Spring)
   >>> print(x)
   Spring
   >>> y = enumSeason(enumSeason.Spring)
   >>> x == y
   True
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top