[Python-ideas] Adding __getter__ to compliment __iter__.
Nick Coghlan
ncoghlan at gmail.com
Thu Jul 18 11:08:18 CEST 2013
On 18 July 2013 16:46, Ron Adam <ron3200 at gmail.com> wrote:
>
>
> These methods would be called by a getter function which starts it by
> calling next on it before returning it.
>
>
> def getter(container):
> """ Get a getter from a container object. """
> g = container.__getter__()
> next(g)
> return g
Let's call it the "builder" protocol instead, since "getter" makes me
think of "itemgetter" and "attrgetter", and this is well worn
territory in Java with "StringBuilder" :)
Let's say we defined the builder protocol this way:
1. Containers may define a "__builder__" method:
def __builder__(self):
"Returns a builder for a *new* instance of this type,
pre-initialised with the contents of self"
2. Builders must define the following methods:
def append(self, item):
"Appends a single item to the builder"
def extend(self, iterable):
"Extends the builder with the contents of an iterable"
__iadd__ = extend
def finish(self):
"Converts the contents of the builder to the final desired type"
And added a new "builder" builtin with the following behaviour:
def builder(obj):
try:
meth = obj.__builder__
except AttributeError:
pass
else:
return meth
return DefaultBuilder(obj)
class DefaultBuilder:
def __init__(self, obj):
if not (hasattr(obj, "copy") and hasattr(obj, "append")
and hasattr(obj, "extend")):
raise TypeError("%r instance cannot be converted to a
builder" % type(r))
self._obj = obj.copy()
def append(self, item):
if self._obj is None: raise RuntimeError("Cannot append to
finished builder")
self._obj.append(item)
def extend(self, iterable):
if self._obj is None: raise RuntimeError("Cannot extend
finished builder")
self._obj.extend(iterable)
__iadd__ = extend
def finish(self):
if self._obj is None: raise RuntimeError("Builder already finished")
result = self._obj
self._obj = None
return result
Then builtin sum() would have the following case added to handle the
builder protocol:
try:
bldr = builder(start)
except TypeError:
pass
else:
for item in iterable:
bldr += item
return bldr.finish()
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list