Aktualnie jestem na etapie odkrywania języka Python, ale widziałem już opinie, że Enum jest zbędny, a nawet niezgodny z jego filozofią. Nie wiem, nie znam się, nie wypowiadam się o tym. Chętnie poznam sensowne argumenty w tym temacie, ale nie zamierzam się w nim zagłębiać. Mój cel to przedstawienie mojego pomysłu na parsowanie ciągów znaków do wartości Enum.
Enum w Python jest bazowo bliższy rozwiązaniu z C#. Widziałem już rozszerzenia zbliżające go znacznie do rozwiazania w języku Java. Przy moich zastsowaniach rozwiązanie bazowe jest zwykle wystarczające. W miejscach gdzie nie jest, klasa OrderedEnum czy IntEnum opisane w dokumentacji Python 3.4. Od razu ostrzegam, że to przykłady rozszerzenia Enum, a nie klasy dostarczone z Python 3.4 w module enum. Moje rozwiązanie należy traktować jako kolejny przykład możliwości rozszerzenia klasy Enum. Docelowo zamierzam złożyć klasy OrderedEnum i swoją (aktualnie zwaną jako ExEnum).
Poniżej znajduje się listing mojego aktualnego rozwiązania.
from enum import Enum class ExEnum(Enum): @classmethod def parse(cls, name): if name in cls.__members__: return cls[name] raise ValueError("{0} is not valid value of {1}".format(name, cls.__name__)) @classmethod def try_parse(cls, name): if name in cls.__members__: return cls[name] return FalseNiestety nie jest możliwe aby oznaczyć klasę ExEnum jako abstrakcyjną. Sama w sobie jest bezużyteczna i służy jako baza, więc powinna być abstrakcyjna, ale nie da się i już. Aby więc skorzystać z ExEnum należy utworzyć klasę z niej dziedziczącą. Można użyć jej jako dowolnego Enuma. Mamy w tym momencie do dyspozycji metody parse i tryparse pozwalające na uzyskanie enuma z ciągu znaków zawierającego jego nazwę.
Przykładowo możemy utworzyć klasę StateEnum jak poniżej.
class StateEnum(ExEnum): starting = 0 started = 1 working = 2 stoped = 3Teraz możemy z niej skorzystać w taki sposób:
>>> StateEnum.parse('started') <stateenum .started:="" 1=""> >>> StateEnum.parse('paused') Traceback (most recent call last): File "<pyshell>", line 1, in <module> StateEnum.parse('paused') File "C:/Python34/tst.py", line 8, in parse raise ValueError("{0} is not valid value of {1}".format(name, cls.__name__)) ValueError: paused is not valid value of StateEnum >>> StateEnum.try_parse('paused') FalseJak widać metoda parse w razie nieistniejącego elementu rzuca wyjątek. Metoda try_parse zwraca w tej sytuacji False. Jest to podyktowane faktem, że wyjątki nie są zbyt lekkie i można je w tym miejscu uznać za zbędne.
Brak komentarzy:
Prześlij komentarz