Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 354 – Aufzählungen in Python

Autor:
Ben Finney <ben+python at benfinney.id.au>
Status:
Abgelöst
Typ:
Standards Track
Erstellt:
20-Dez-2005
Python-Version:
2.6
Post-History:
20-Dez-2005
Ersetzt-Durch:
435

Inhaltsverzeichnis

Ablehnungsbescheid

Dieser PEP wurde abgelehnt. Er passt nicht gut in eines der bestehenden Module (wie collections), und die Python-Standardbibliothek vermeidet es, viele einzelne Datenstrukturen in eigenen Modulen zu haben. Außerdem hat der PEP kein breites Interesse hervorgerufen. Für diejenigen, die Aufzählungen benötigen, gibt es Rezepte im Cookbook und PyPI-Pakete, die diese Bedürfnisse erfüllen.

Hinweis: Dieser PEP wurde durch PEP 435, der im Mai 2013 akzeptiert wurde, abgelöst.

Zusammenfassung

Dieser PEP spezifiziert einen Aufzählungs-Datentyp für Python.

Eine Aufzählung ist eine exklusive Menge von symbolischen Namen, die an beliebige eindeutige Werte gebunden sind. Werte innerhalb einer Aufzählung können iteriert und verglichen werden, aber die Werte haben keine inhärente Beziehung zu Werten außerhalb der Aufzählung.

Motivation

Die Eigenschaften einer Aufzählung sind nützlich für die Definition einer unveränderlichen, zusammenhängenden Menge von konstanten Werten, die eine definierte Reihenfolge, aber keine inhärente semantische Bedeutung haben. Klassische Beispiele sind Wochentage (Sonntag bis Samstag) und Schulnoten ('A' bis 'D' und 'F'). Weitere Beispiele sind Fehlerstatuswerte und Zustände innerhalb eines definierten Prozesses.

Es ist möglich, einfach eine Sequenz von Werten eines anderen Basistyps, wie z. B. int oder str, zu definieren, um diskrete beliebige Werte darzustellen. Eine Aufzählung stellt jedoch sicher, dass solche Werte von anderen eindeutig sind und dass Operationen ohne Bedeutung ("Mittwoch mal zwei") für diese Werte nicht definiert sind.

Spezifikation

Ein Aufzählungstyp wird aus einer Sequenz von Argumenten für den Konstruktor des Typs erstellt

>>> Weekdays = enum('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat')
>>> Grades = enum('A', 'B', 'C', 'D', 'F')

Aufzählungen ohne Werte sind bedeutungslos. Die Ausnahme EnumEmptyError wird ausgelöst, wenn der Konstruktor ohne Wertargumente aufgerufen wird.

Die Werte werden an Attribute des neuen Aufzählungsobjekts gebunden

>>> today = Weekdays.mon

Die Werte können verglichen werden

>>> if today == Weekdays.fri:
...     print "Get ready for the weekend"

Werte innerhalb einer Aufzählung können nicht sinnvoll verglichen werden, außer mit Werten aus derselben Aufzählung. Die Vergleichsoperationen geben NotImplemented [1] zurück, wenn ein Wert aus einer Aufzählung mit einem Wert verglichen wird, der nicht aus derselben Aufzählung stammt oder von einem anderen Typ ist.

>>> gym_night = Weekdays.wed
>>> gym_night.__cmp__(Weekdays.mon)
1
>>> gym_night.__cmp__(Weekdays.wed)
0
>>> gym_night.__cmp__(Weekdays.fri)
-1
>>> gym_night.__cmp__(23)
NotImplemented
>>> gym_night.__cmp__("wed")
NotImplemented
>>> gym_night.__cmp__(Grades.B)
NotImplemented

Dies ermöglicht den Erfolg der Operation und die Auswertung zu einem booleschen Wert

>>> gym_night = Weekdays.wed
>>> gym_night < Weekdays.mon
False
>>> gym_night < Weekdays.wed
False
>>> gym_night < Weekdays.fri
True
>>> gym_night < 23
False
>>> gym_night > 23
True
>>> gym_night > "wed"
True
>>> gym_night > Grades.B
True

Das Umwandeln eines Werts aus einer Aufzählung in einen str ergibt den String, der für diesen Wert beim Erstellen der Aufzählung angegeben wurde.

>>> gym_night = Weekdays.wed
>>> str(gym_night)
'wed'

Der Sequenzindex jedes Werts aus einer Aufzählung wird als Integer über das index-Attribut dieses Werts exportiert.

>>> gym_night = Weekdays.wed
>>> gym_night.index
3

Eine Aufzählung kann iteriert werden und gibt ihre Werte in der Reihenfolge zurück, in der sie bei der Erstellung der Aufzählung angegeben wurden.

>>> print [str(day) for day in Weekdays]
['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']

Werte aus einer Aufzählung sind hashable und können als Dictionary-Schlüssel verwendet werden.

>>> plans = {}
>>> plans[Weekdays.sat] = "Feed the horse"

Die normale Verwendung von Aufzählungen besteht darin, eine Menge möglicher Werte für einen Datentyp bereitzustellen, die dann verwendet werden können, um auf andere Informationen über die Werte abzubilden.

>>> for report_grade in Grades:
...     report_students[report_grade] = \
...         [s for s in students if students.grade == report_grade]

Begründung – Andere in Betracht gezogene Designs

Alles in einer Klasse

Einige Implementierungen haben die Aufzählung und ihre Werte alle als Attribute eines einzelnen Objekts oder einer Klasse.

Dieser PEP spezifiziert ein Design, bei dem die Aufzählung ein Container ist und die Werte einfache vergleichbare Elemente sind. Es wurde angenommen, dass der Versuch, alle Eigenschaften einer Aufzählung in einer einzigen Klasse unterzubringen, das Design ohne offensichtlichen Nutzen verkompliziert.

Metaklasse zur Erstellung von Aufzählungsklassen

Die in diesem PEP spezifizierten Aufzählungen sind Instanzen eines enum-Typs. Einige alternative Designs implementieren jede Aufzählung als eigene Klasse und eine Metaklasse, um gemeinsame Eigenschaften aller Aufzählungen zu definieren.

Eine Motivation dafür, eine Klasse (anstatt einer Instanz) für jede Aufzählung zu haben, ist die Möglichkeit, Unterklassen von Aufzählungen zu erstellen, die eine bestehende Aufzählung erweitern und ändern. Eine Klasse impliziert jedoch, dass Instanzen dieser Klasse erstellt werden; es ist schwer vorstellbar, was es bedeutet, separate Instanzen einer "Wochentags"-Klasse zu haben, wobei jede Instanz alle Tage enthält. Dies führt normalerweise dazu, dass jede Klasse dem Singleton-Muster folgt, was das Design weiter verkompliziert.

Im Gegensatz dazu spezifiziert dieser PEP Aufzählungen, von denen nicht erwartet wird, dass sie erweitert oder geändert werden. Es ist natürlich möglich, eine neue Aufzählung aus den String-Werten einer bestehenden zu erstellen oder sogar den enum-Typ zu unterklassen, falls gewünscht.

Attribute von Aufzählungswerten verbergen

Ein früheres Design hatte die aufzählbaren Werte, die so viel wie möglich über ihre Implementierung verbargen, bis hin zum Nicht-Exportieren des String-Schlüssels und des Sequenzindexes.

Das Design in diesem PEP erkennt an, dass Programme es oft praktisch finden werden, den Aufzählungstyp des aufzählbaren Werts, den Sequenzindex und den für den Wert angegebenen String-Schlüssel zu kennen. Diese werden vom aufzählbaren Wert als Attribute exportiert.

Implementierung

Dieses Design basiert teilweise auf einem Rezept [2] aus dem Python Cookbook.

Das PyPI-Paket enum [3] bietet eine Python-Implementierung der in diesem PEP beschriebenen Datentypen.

Referenzen und Fußnoten


Quelle: https://github.com/python/peps/blob/main/peps/pep-0354.rst

Zuletzt geändert: 2025-02-01 08:59:27 GMT