ASPN ActiveState Programmer Network
sign in | join ActiveState, a division of Sophos
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups | Web Services
Submit Recipe
My Recipes

All Recipes
All Cookbooks


View by Category

Title: Caching and aliasing with descriptors
Submitter: Denis Otkidach (other recipes)
Last Updated: 2004/04/05
Version no: 1.0
Category: OOP

 

Not Rated yet


Description:

A few simple discriptor classes to compute and cache attribute value on demand and to define attribute as alias to other.

Source: Text Source

class CachedAttribute(object):
    '''Computes attribute value and caches it in instance.

    Example:
        class MyClass(object):
            def myMethod(self):
                # ...
            myMethod = CachedAttribute(myMethod)
    Use "del inst.myMethod" to clear cache.'''

    def __init__(self, method, name=None):
        self.method = method
        self.name = name or method.__name__

    def __get__(self, inst, cls):
        if inst is None:
            return self
        result = self.method(inst)
        setattr(inst, self.name, result)
        return result


class CachedClassAttribute(object):
    '''Computes attribute value and caches it in class.

    Example:
        class MyClass(object):
            def myMethod(cls):
                # ...
            myMethod = CachedClassAttribute(myMethod)
    Use "del MyClass.myMethod" to clear cache.'''

    def __init__(self, method, name=None):
        self.method = method
        self.name = name or method.__name__

    def __get__(self, inst, cls):
        result = self.method(cls)
        setattr(cls, self.name, result)
        return result


class ReadAliasAttribute(object):
    '''If not explcitly assigned this attribute is an alias for other.

    Example:
        class Document(object):
            title='?'
            shortTitle=ReadAliasAttribute('title')'''

    def __init__(self, name):
        self.name = name

    def __get__(self, inst, cls):
        if inst is None:
            return self
        return getattr(inst, self.name)


class AliasAttribute(ReadAliasAttribute):
    '''This attribute is an alias for other.

    Example:
        class Document(object):
            newAttrName=somevalue
            deprecatedAttrName=AliasAttribute('newAttrName')'''

    def __set__(self, inst, value):
        setattr(inst, self.name, value)

    def __delete__(self, inst):
        delattr(inst, self.name)

Discussion:

First two decriptor classes are usful for lazy attribute evaluation. Note, that after it's evaluated there is no overhead since cached value is stored in instance/class __dict__.
ReadAliasAttribute is intended for cases when one attribute should bound to other by default. And AliasAttribute can be used when you find a better name for an attribute, but want keep compatibility.



Add comment

No comments.

SEARCH
advanced | search help


Highest rated recipes:

1. Finite State Machine ...

2. General Class for ...

3. Lightweight XML ...

4. Reading and writing mbox ...

5. How to Set Environment ...

6. automatically upgrade ...

7. Stateful Objects use ...

8. Directory Walker ...

9. IPy Notify

10. Generator Attributes


Privacy Policy | Email Opt-out | Feedback | Syndication
© 2004 ActiveState, a division of Sophos All rights reserved