2017-01-18 10 views
7

Piszę kod Pythona 2 przez około 3 lata, i chociaż znam go już od dawna, zaczęliśmy używać ich w naszym projekcie (backported - pypi package enum34).Co to jest przydatny przypadek do wyliczenia w python?

Chciałbym zrozumieć, kiedy ich użyć.

Jednym z miejsc, w którym zaczęliśmy z nich korzystać, było odwzorowanie niektórych wyliczeń poziomu bazy danych postgresów na wartości w pythonach. Dlatego mamy tej klasy ENUM

class Status(enum.Enum): 
    active = 'active' 
    inactive = 'inactive' 

ale potem podczas korzystania z tych, jakie skończyło się je tak:

if value == Status.active.value: 
    ... 

I tak stosując stałe teksty w tym przypadku jest mniej przydatne niż tylko za pomocą bardziej proste klasy, jak to

class Status(object): 
    active = 'active' 
    inactive = 'inactive' 

Bo moglibyśmy to wykorzystać łatwiej, jak value == Status.active.

Do tej pory jedynym miejscem, w którym znalazłem to przydatne - choć nie tak przydatne, jak bym chciał - jest w docstrukcji. Zamiast jawnie mówić, że dozwolone wartości to "aktywne" i "nieaktywne", mogę po prostu oświadczyć, że mój formalny parametr oczekuje członka wyliczenia statusu (bardziej przydatny, gdy istnieje więcej statusów)

Tak naprawdę nie Węzeł, jaki jest ich dokładny przypadek użycia - nie wiem, jak są lepsze niż stałe łańcuchowe.

Krótko mówiąc: kiedy używać wyrażeń?

+0

Jeśli wybierzesz napisy, DocString może również powiedzieć "musi być jedną ze stałych zdefiniowanych w klasie" Status ". – 5gon12eder

+0

Aby odpowiedzieć na pytanie tytułowe: [Python enum, kiedy i gdzie użyć?] (Http://stackoverflow.com/q/22586895/208880) –

Odpowiedz

3

Kilka punktów:

  • mozesz Enum klasa może używać str jako wstawek
  • niektóre warstwy bazy danych pozwalają na konwersję przechowywanych danych na typy danych Pythona

Dla pierwszego punktu :

class Status(str, Enum): 
    active = 'active' 
    inactive = 'inactive' 

... 

if value == Status.active: 
    ... 

Za drugi punkt:

Mam tu niewielkie doświadczenie, ale wierzę, że SQLAlchemy to zrobi.

1

Używam Enum najczęściej w projektowaniu GUI. Wyobraź sobie, że masz przycisk radiowy, taki jak enter image description here

Przedstawia on listę stałych wyborów, więc pod maską jest dobrze reprezentowany przez Enum. Oznacza to, że jeśli użytkownik kliknie przycisk 2, może zostać zwrócone Enum.Choice.Choice2 przez niektóre wywołania zwrotne. Jest to lepsze niż zwracanie int 2 lub ciągu znaków "choice 2", ponieważ nie ma nic do sprawdzenia ich później. Innymi słowy, jeśli zmienisz "choice 2" na "user choice 2", możesz potencjalnie rozbić podzespoły spodziewające się oryginalnego symbolu.

Pomyśl o Enum jako wygodnym skrócie do prezentowania statycznego zestawu wyborów, zamiast tworzyć standardowe klasy obiektów.

Znalazłem, że Enum w Javie (i innych statycznie napisanych językach, jak sądzę) jest nieco bardziej użyteczny, ponieważ możesz zadeklarować je w sygnaturze metody.Na przykład, metoda może mieć podpis,

public void (Enum.Choice, mychoice) 

Zamiast

public void (String, mychoice) 

W drugim przypadku, użytkownik może wiedzieć z wyprzedzeniem, że mychoice powinny być "foo" lub "bar", ale co jeśli przechodzą one w "baz", która jest nieprawidłowa. Zastosowanie Enum spowoduje, że nieprawidłowe dane wejściowe nie będą mogły zostać przekazane do metody, ponieważ Enum.Choice ma tylko pola foo i bar. Jeśli spróbujesz, nie możesz utworzyć opcji wyboru.

Przepraszam, zabłądziłem na Jawę. Czy ten temat nie jest zbyt pomocny?

1

Wystąpił problem, ponieważ ORM nie odwzorowuje wartości bazy danych na obiekt Enum. Gdyby tak było, nie musiałbyś zajmować się .value.

Alternatywą byłoby coś takiego:

if Status(value) is Status.active: ponieważ konstruktor tworzy Enum z danego argumentu.

+0

Dobre łapanie @ EthanFurman, napisałem to z mojego telefonu i byłem niechlujny. Wymieniłem '==' na 'jest' –

+0

Ah, to wyjaśnia kapitał' If'. ;) –