Może wartość a może None - implementacja wzorca w Pythonie
pymaybe implementuje monadę może
w Pytonie. Pozwala ona traktować brak wartości (None) tak samo jak wartość (nie-None). Wzorca tego można użyć by uniknąć bloków try/except, czy bloków if.
pymaybe możemy zainstalować poprzez pip. Biblioteka działa zarówno pod Pythonem 2 jak i 3.
Sposób działania jest prosty. Do funkcji maybe przekazujemy obiekt i otrzymujemy obiekt typu Something. Możemy na nim operować tak jak na oryginalnym obiekcie. Jeżeli w trakcie operacji rzucony zostałby wyjątek to obiekt Something go złapie i zwróci None lub inną wartość zdefiniowaną opcjonalne poprzez metodę or_else().
Oto kilka przykładów:
from pymaybe import maybe
d = {}
maybe(d)['foo']['bar']
>>> None
maybe(d)['foo']['bar'].or_else('No data provided')
>>> 'No data provided'
maybe(d)['foo']['bar'].or_else(lambda: 'No data provided')
>>> 'No data provided'
Oprócz or_else dostępne są też dwie metody is_some oraz is_none pozwalające testować wartość:
from django.contrib.auth.models import AnonymousUser
from pymaybe import maybe
AnonymousUser().get_full_name()
>>> AttributeError: 'AnonymousUser' object has no attribute 'get_full_name'
maybe(AnonymousUser()).get_full_name()
>>> None
maybe(AnonymousUser()).get_full_name().is_some()
>>> False
maybe(AnonymousUser()).get_full_name().is_none()
>>> True
Oczywiście nie należy przesadzać z użyciem tego wzorca, gdy jest on zachłanny i będzie łapać więcej wyjątków niż byśmy chcieli (np. umknąć może nam literówka w nazwie metody, klucza, czy nieoczekiwany typ obiektu). Dokładne pokrycie testami jednostkowymi zalecane. Trzeba uwzględnić też np. zmianę formatu danych dostarczanych przez API - w takich przypadkach źle użyte maybe zawsze będzie zwracać wartość alternatywną i nie dowiemy się o tym bo żaden wyjątek ani log nie zostanie zapisany. Z wielką mocą przychodzi wielka odpowiedzialność.
Comment article