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ść.

RkBlog

Podstawy Pythona, 1 November 2015

Comment article
Comment article RkBlog main page Search RSS Contact