Created
July 15, 2016 17:08
-
-
Save wsanchez/5d751e78d1d7578cf7ab7b9bca24bbe3 to your computer and use it in GitHub Desktop.
Python Optional
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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