[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

AltStyle によって変換されたページ (->オリジナル) /