> Have you seen PyLINQ? It has a similar approach to operating on > collections, returning a PyLINQ object after each call to facilitate > chaining. https://github.com/kalessin/PyLINQ/blob/master/pylinq/linq.py
I hadn't seen it previously. I am a VERY heavy user of SQL Alchemy though, and I am sure chaining generative ClauseElements/Queries/etc, has burned some patterns into my subconscious at this point. > This is a personal opinion on the code, but I'd move instantiating the > new ElementwiseProxy out of each method and into its own decorator: > > # declare this outside of the class > def chainable(fn): > def _(self, *args, **kwargs): > return ElementwiseProxy(fn(self, *args, **kwargs), self) > return _ > > This way, each method that is chainable is a little more obvious > without inspecting the code, and the method body itself is only doing > what the method says it does: > > @chainable > def __add__(self, other): > return (e + other for e in object.__getattribute__(self, > "iterable")) This is a reasonable suggestion and I will play with something along those lines soon. > Incidentally, displaying an ElementwiseProxy instance doesn't go down > well with iPython: > > In [1]: from elementwise import * > > In [2]: e = ElementwiseProxy(['one','two','three']) > > In [3]: e > Out[3]: ERROR: An unexpected error occurred while tokenizing input > The following traceback may be corrupted or invalid > The error message is: ('EOF in multi-line statement', (6, 0)) I love IPython, but it has had known problems with iterators for years. A long time ago, I agonized over what I thought was a bug in my code where itertools.count would skip numbers in IPython, but my unit tests all passed. Everything should work fine if you tuple() it first. Nathan -- http://mail.python.org/mailman/listinfo/python-list