2016-10-13 3 views
3

Was ist die Pythonic Möglichkeit, den Aufrufer einer Funktion zu sagen, welche Werte ein bestimmter Parameter unterstützt?Pythonic Weg um Enums

Er ist ein Beispiel für PyQt (für GUI). Sagen, dass ich eine Checkbox haben,

class checkbox(object): 
    .... 
    def setCheckState(self, value): 
     .... 

Hier setCheckState() nur oder ungeprüft geprüft erwarten.

PyQt verwendet eine integrierte Enumeration (d. H. Qt.Checked oder Qt.Unchecked), aber das ist schrecklich. Ich bin ständig in der Dokumentation auf der Suche nach dem Enum für das Objekt, mit dem ich arbeite.

Offensichtlich ist PyQt in einem unpythonischen C++ sytle geschrieben. Wie sollte dieses oder ein ähnliches Problem in Python behandelt werden? Laut PEP 435 scheinen Enums eine neue Ergänzung der Sprache und für sehr spezifische Anwendungen zu sein, also würde ich annehmen, dass es einen besseren Weg gibt, damit umzugehen?

Ich möchte den Code, den ich schreibe, einfach zu verwenden, wenn meine Funktionen bestimmte Parameterwerte erfordern - fast wie eine Combobox für Funktionen.

+0

Enums wurden genau eingeführt, weil jeder seinen eigenen Ersatz ersetzte. Wenn Sie eine Aufzählung wünschen, verwenden Sie eine Aufzählung.Wenn Sie nur zwei Zustände haben, sollten Sie einen booleschen Wert verwenden: 'def setCheckState (self, checked = True):'. – MisterMiyagi

+0

Inversion-of-Control-Befürworter würden argumentieren, dass es drei separate Funktionen geben sollte, die kein * any * Argument verwenden: "checkbox.set_checked()", "checkbox.set_unchecked()" und "checkbox.toggle()" '. – chepner

+0

Ich schätze, das ist eher meinungsbezogen als ich dachte, ich hatte gehofft, dass es wie bei den meisten Dingen in Python einen richtigen Weg geben würde. –

Antwort

1

Die Ein offensichtlicher Weg ist Funktion Anmerkungen.

class CheckBox(enum.Enum): 
    Off = 0 
    On = 1 

def setCheckState(self, value: CheckBox): 
    ... 

Dies sagt ganz deutlich, dass value eine Instanz von CheckBox sein sollte. Enum zu haben, macht das ein bisschen einfacher.

Anmerkungen selbst werden in 2.7 nicht direkt unterstützt. Zu den üblichen Problemumgehungen gehört das Einfügen dieser Informationen in die Funktion doc string (wo verschiedene Tools sie finden können) oder in Kommentare (wie wir bereits wussten).

Wenn Sie nach einer Methode für Ihren eigenen Code suchen: Verwenden Sie einen Beschriftungsdekorator. Dies hat den Vorteil der Weiterbildung in 3+ arbeiten:

class annotate(object): 
    def __init__(self, **kwds): 
     self.kwds = kwds 
    def __call__(self, func): 
     func.__annotations__ = self.kwds 

@annotate(value=CheckBox) 
def setCheckState(self, value): 
    ... 

Um ein robusten Dekorateur es überprüfen soll, dass der Inhalt von kwds paßt die Funktion Parameternamen.

+0

Funktionsanmerkungen sind in Python 2.7 nicht verfügbar. – chepner

+0

Das würde erklären, warum ich bisher noch nichts von ihnen gehört habe. –

+0

Ah, ich habe das 2.7-Tag verpasst, sorry. –

0

, die den Trick

import collections 

def create_enum(container, start_num, *enum_words): 
    return collections.namedtuple(container, enum_words)(*range(start_num, start_num + len(enum_words))) 

Switch = create_enum('enums', 1, 'On', 'Off') 

Schalter ist Ihr Enum tun:

In [20]: Switch.On 
Out[20]: 1 

In [21]: Switch.Off 
Out[21]: 2 

OK, habe ich den Fehler meiner Wege - ich gemischt Darstellung mit Wert.

Dennoch, wenn Sie einen größeren Bereich aufzählen möchten - in meinem gefälschten Ansatz müssen Sie Werte nicht manuell hinzufügen. Natürlich, wenn Sie fortlaufende Nummern haben.

Und ich hasse extra tippen :-)

+0

Python hat jetzt "Enum", keine Notwendigkeit, falsche zu erstellen. –

+0

@EthanFurman, leider sind die Werte von Switch.Off und Switch on, die mit enum erstellt wurden, nicht 0 und 1 - sie sind Typen und Sie benötigen weitere Dereferenzierung, um 0 und 1 zu erhalten. – volcano

+1

Nicht, wenn Sie 'enum.IntEnum' verwenden. –

Verwandte Themen