Делаем Java-подобный Optional в Python
Опубликовано 25 November 2016 в Python
В некоторых случаях использование None может превратить код в нечитаемую и неподдерживаемую кашу. К примеру, если есть необходимость отличить "пустое" значение от отсутствия значения для целочисленного ввода, когда 0 не может использоваться в качестве этого "пустого" значения, обойтись только используя None очень сложно. Одно из возможных значений использовать что-то подобное Optional из Java.
Конечно, Optional не совсем "питонячий путь". В некоторых случаях можно использовать исключения, как предлагается в этой дискуссии на StackOverflow.
В моем случае это не работало. Так что я решил сделать свою имплементацию Optional. И в итоге я получил чистый и хорошо читаемый код. После дискуссии с коллегами, мы решили использовать имена из Haskell, так как то, что у меня получилось больше походило на хаскелльный тип Maybe, чем на джавовый Optional. Вот что у меня получилось:
from abc import ABCMeta, abstractmethod
class Maybe(object):
__metaclass__ = ABCMeta
@abstractmethod
def get(self, default=None):
pass
class Just(Maybe):
def __init__(self, value):
self.value = value
def __nonzero__(self):
return True
def get(self, default=None):
return self.value
class Nothing(Maybe):
def __nonzero__(self):
return False
def get(self, default=None):
return default
После интеграции в существующий кода, я могу с уверенностью сказать, что решение работает идеально. Возможно, надо бы добавить еще красивое представление для этих объектов. Но в целом даже без этого с объектами типа Maybe очень удобно работать при отладке: в отличие от None, понятно что из себя представляет то или иное значение.
Если нужно что-то более сложное, попробуйте hask. Но будьте готовы к тому, что у них слишком много хаскелля в их питоне.
Если мой подход кажется не самым удачным, можно попробовать и другие. К примеру, почерпнутых из статьи Python Option Types.
Возник вопрос? Мне всегда можно написать в Twitter: avkorablev