Skip to content

Instantly share code, notes, and snippets.

@asyncee
Created March 23, 2016 15:32
Show Gist options
  • Save asyncee/d57ad89267d16962ae75 to your computer and use it in GitHub Desktop.
Save asyncee/d57ad89267d16962ae75 to your computer and use it in GitHub Desktop.
Method chaining in python example
import copy
from collections import namedtuple, Sequence
Item = namedtuple('Item', 'name, price')
items = [
Item('apple', 10.0),
Item('banana', 12.0),
Item('orange', 8.0),
Item('coconut', 50.0),
]
class Query(Sequence):
def __init__(self, items):
self.items = items
def __getitem__(self, i):
return self.items[i]
def __len__(self):
return len(self.items)
def _clone(self):
#return Query(self.items)
return copy.deepcopy(self)
def first(self):
q = self._clone()
return next(iter(q), None)
def last(self):
q = self._clone()
try:
return q[-1]
except KeyError:
return None
def values(self, attr):
q = self._clone()
return [getattr(o, attr) for o in q]
def filter(self, cond):
"""
Filter by condition.
Condition must be a function taking one argument (an object),
and returning True or False.
"""
q = self._clone()
return Query([o for o in q if cond(o)])
@property
def total(self):
return sum(self.values('price'))
if __name__ == "__main__":
q = Query(items)
q2 = Query(items)
assert id(q.items) != id(q2.items)
assert q.first() == items[0]
assert q.last() == items[-1]
assert q.values('name') == ['apple', 'banana', 'orange', 'coconut']
assert q.values('price') == [10.0, 12.0, 8.0, 50.0]
assert q.filter(lambda x: x.price > 30).values('name') == ['coconut']
assert q.filter(lambda x: x.price > 30).total == 50.0
assert q.total == 80.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment