Created
February 23, 2018 20:33
-
-
Save romeroyonatan/6bab27b4d1d5e2d5e9a6f395ac1e1257 to your computer and use it in GitHub Desktop.
Lazy chainable operator
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
import operator | |
class Operator(object): | |
'''Chaineable and lazy operations''' | |
def __init__(self, value, *args): | |
self._value = value | |
self._args = args | |
def value(self): | |
if callable(self._value): | |
return self._value(*map(Operator.resolve, self._args)) | |
return self._value | |
@staticmethod | |
def resolve(arg): | |
if isinstance(arg, Operator): | |
return arg.value() | |
return arg | |
def __add__(self, value): | |
return Operator(operator.add, self, value) | |
def __radd__(self, value): | |
return Operator(operator.add, value, self) | |
def __sub__(self, value): | |
return Operator(operator.sub, self, value) | |
def __rsub__(self, value): | |
return Operator(operator.sub, value, self) | |
def __mul__(self, value): | |
return Operator(operator.mul, self, value) | |
def __rmul__(self, value): | |
return Operator(operator.mul, value, self) | |
def __div__(self, value): | |
return Operator(operator.div, self, value) | |
def __rdiv__(self, value): | |
return Operator(operator.div, value, self) | |
def __repr__(self): | |
if self._args: | |
return 'Operator(value=%r, args=%r)' % (self._value, self._args) | |
return 'Operator(%r)' % self._value | |
def __str__(self): | |
return str(self.value()) |
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
>>> from chain import Operator | |
>>> operators = [Operator(x) for x in range(10)] | |
>>> operators | |
[Operator(0), Operator(1), Operator(2), Operator(3), Operator(4), Operator(5), Operator(6), Operator(7), Operator(8), Operator(9)] | |
>>> sum(operators) | |
Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(Operator(value=<built-in function add>, args=(0, Operator(0))), Operator(1))), Operator(2))), Operator(3))), Operator(4))), Operator(5))), Operator(6))), Operator(7))), Operator(8))), Operator(9))) | |
>>> result=_ | |
>>> result.value() | |
45 | |
>>> result = Operator(1) + Operator(10) / Operator(5) | |
>>> result.value() | |
3 | |
>>> result = Operator(1) + 10 / 5 | |
>>> result.value() | |
3 | |
>>> result = 1 + Operator(2) | |
>>> result.value() | |
3 | |
>>> result = 1 + Operator(2) / 0 | |
>>> result # Because operation is lazy, exception not raised | |
Operator(value=<built-in function add>, args=(1, Operator(value=<built-in function div>, args=(Operator(2), 0)))) | |
>>> result.value() | |
Traceback (most recent call last): | |
File "<stdin>", line 1, in <module> | |
File "chain.py", line 13, in value | |
return self._value(*map(Operator.resolve, self._args)) | |
File "chain.py", line 19, in resolve | |
return arg.value() | |
File "chain.py", line 13, in value | |
return self._value(*map(Operator.resolve, self._args)) | |
ZeroDivisionError: integer division or modulo by zero | |
>>> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment