Skip to content

Instantly share code, notes, and snippets.

@wsanchez
Created July 15, 2016 17:08
Show Gist options
  • Save wsanchez/5d751e78d1d7578cf7ab7b9bca24bbe3 to your computer and use it in GitHub Desktop.
Save wsanchez/5d751e78d1d7578cf7ab7b9bca24bbe3 to your computer and use it in GitHub Desktop.
Python Optional
"""
Optional.
"""
from __future__ import print_function
_novalue = object()
class NoValuePresentError(ValueError):
"""
No value present in optional.
"""
class Optional(object):
"""
Object that either contains a value or is empty.
"""
def __init__(self, value=_novalue):
"""
Initialize an optional with the given value. If no value is given, the
optional is empty.
"""
self._value = value
def __repr__(self):
if self._value is _novalue:
value = ""
else:
value = repr(self._value)
return "{}({})".format(self.__class__.__name__, value)
def __eq__(self, other):
if isinstance(other, Optional):
self._value == other._value
return False
def __hash__(self):
return hash(self._value)
def present(self):
"""
Return L{True} if this optional contains a value, L{False} otherwise.
"""
return self._value is not _novalue
def value(self, default=_novalue):
"""
Return the contained value, if present. If no value is present, return
C{default} if provided by the caller, otherwise raise
L{NoValuePresentError}.
"""
if self._value is _novalue:
if default is _novalue:
raise NoValuePresentError()
else:
return default
else:
return self._value
def valueElse(self, f, *args, **kwargs):
"""
Return the contained value, if present. If no value is present, return
the result of calling C{f} with the given C{args} and C{kwargs}.
"""
if self._value is _novalue:
return f(*args, **kwargs)
else:
return self._value
if __name__ == "__main__":
empty = Optional()
none = Optional(None)
foo = Optional("foo")
for optional in (empty, none, foo):
print(optional)
print("present:", optional.present())
try:
print("value:", optional.value())
except:
print("value: (raised exception)")
print("value default:", optional.value("(default)"))
print("value else:", optional.valueElse(lambda: "(else)"))
print()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment