diff options
| author | Michael Merickel <michael@merickel.org> | 2012-04-10 23:20:11 -0500 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2012-04-10 23:20:11 -0500 |
| commit | 5473f06c9c51ce4bd5f391a240e7b9b278137c53 (patch) | |
| tree | b1d2093324b0fb518aaf77213dfef599250acc2d | |
| parent | 55747c9487422222f963ba843fdbeb3afc2df74e (diff) | |
| download | pyramid-5473f06c9c51ce4bd5f391a240e7b9b278137c53.tar.gz pyramid-5473f06c9c51ce4bd5f391a240e7b9b278137c53.tar.bz2 pyramid-5473f06c9c51ce4bd5f391a240e7b9b278137c53.zip | |
refactored set_property to support multiple properties in the same subclass
| -rw-r--r-- | pyramid/util.py | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/pyramid/util.py b/pyramid/util.py index cca1872b7..ff6ac8f4a 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -20,6 +20,59 @@ class InstancePropertyMixin(object): on the class itself. """ + def _make_property(self, callable, name=None, reify=False): + """ Convert a callable into one suitable for adding to the + instance. This will return a 2-tuple containing the computed + (name, property) pair. + """ + + is_property = isinstance(callable, property) + if is_property: + fn = callable + if name is None: + raise ValueError('must specify "name" for a property') + if reify: + raise ValueError('cannot reify a property') + elif name is not None: + fn = lambda this: callable(this) + fn.__name__ = name + fn.__doc__ = callable.__doc__ + else: + name = callable.__name__ + fn = callable + if reify: + import pyramid.decorator # avoid circular import + fn = pyramid.decorator.reify(fn) + elif not is_property: + fn = property(fn) + + return name, fn + + def _set_properties(self, properties): + """ Create several properties on the instance at once. + + This is a more efficient version of + :meth:`pyramid.util.InstancePropertyMixin.set_property` which + can accept multiple ``(name, property)`` pairs generated via + :meth:`pyramid.util.InstancePropertyMixin._make_property`. + + ``attrs`` is a sequence of 2-tuples *or* a data structure with + an ``.items()`` method which returns a sequence of 2-tuples + (presumably a dictionary). It will be used used to add several + properties to the instance in a manner that is more efficient + than simply calling ``set_property`` repeatedly. + """ + + if hasattr(properties, 'items'): + attrs = properties.items() + else: + attrs = properties + attrs = dict(properties) + + parent = self.__class__ + cls = type(parent.__name__, (parent, object), attrs) + self.__class__ = cls + def set_property(self, callable, name=None, reify=False): """ Add a callable or a property descriptor to the instance. @@ -31,12 +84,11 @@ class InstancePropertyMixin(object): A property may also be reified via the :class:`pyramid.decorator.reify` decorator by setting ``reify=True``, allowing the result of the evaluation to be - cached. Thus the value of the property is only computed once for - the lifetime of the object. + cached. Using this method, the value of the property is only + computed once for the lifetime of the object. ``callable`` can either be a callable that accepts the instance - as - its single positional parameter, or it can be a property + as its single positional parameter, or it can be a property descriptor. If the ``callable`` is a property descriptor, the ``name`` @@ -73,30 +125,8 @@ class InstancePropertyMixin(object): >>> foo.y # notice y keeps the original value 1 """ - - is_property = isinstance(callable, property) - if is_property: - fn = callable - if name is None: - raise ValueError('must specify "name" for a property') - if reify: - raise ValueError('cannot reify a property') - elif name is not None: - fn = lambda this: callable(this) - fn.__name__ = name - fn.__doc__ = callable.__doc__ - else: - name = callable.__name__ - fn = callable - if reify: - import pyramid.decorator - fn = pyramid.decorator.reify(fn) - elif not is_property: - fn = property(fn) - attrs = { name: fn } - parent = self.__class__ - cls = type(parent.__name__, (parent, object), attrs) - self.__class__ = cls + prop = self._make_property(callable, name=name, reify=reify) + self._set_properties([prop]) class WeakOrderedSet(object): """ Maintain a set of items. |
