Metadata-Version: 2.4
Name: lazyutils
Version: 0.3.3
Summary: Lazy accessor and other tools for deferred evaluation.
Home-page: http://github.com/fabiommendes/lazyutils/
Author: Fábio Macêdo Mendes
Author-email: fabiomacedomendes@gmail.com
Platform: any
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Libraries
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: python-boilerplate; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: home-page
Dynamic: license-file
Dynamic: platform
Dynamic: provides-extra
Dynamic: summary

Lazyutils provides a few simple utilities for lazy evaluation of code.


Lazy attribute
==============

The lazy decorator defines an attribute with deferred initialization::

.. code::python
    import math
    from lazyutils import lazy

    class Vec:
        def __init__(self, x, y):
            self.x, self.y = x, y

        @lazy
        def magnitude(self):
            print('computing...')
            return math.sqrt(self.x**2 + self.y**2)

Now the ``magnitude`` attribute is initialized and cached upon first use:

>>> v = Vec(3, 4)
>>> v.magnitude
computing...
5.0

The attribute is writable and apart from the deferred initialization, it behaves
just like any regular Python attribute.

>>> v.magnitude = 42
>>> v.magnitude
42

Lazy attributes can be useful either to simplify the implementation of the
__init__ method of objects that initialize a great number or variables or as an
optimization that delays potentially expensive computations that may not be
necessary in the object's lifecycle.


Delegation
==========

The delegate_to() function delegates some attribute to an attribute during the
class definition::

.. code::python
    from lazyutils import delegate_to
    
    class Arrow:
        magnitude = delegate_to('vector')

        def __init__(self, vector, start=Vec(0, 0)):
            self.vector = vector
            self.start = start

Now, the ``.magnitude`` attribute of ``Arrow`` instances is delegated to
``.vector.magnitude``. Delegate fields are useful in class composition when one
wants to expose a few selected attributes from the inner objects. delegate_to()
handles attributes and methods with no distinction.


>>> a = Arrow(Vec(6, 8))
>>> a.magnitude
computing...
10.0


Aliasing
========

Aliasing is a very simple form of delegation. We can create simple aliases for
attributes using the alias() and readonly() functions::

    class MyArrow(Arrow):
        abs_value = readonly('magnitude')
        origin = alias('start')

This exposes two additional properties: "abs_value" and "origin". The first is
just a read-only view on the "magnitude" property. The second exposes read and
write access to the "start" attribute.

