Another method of lazy, cached evaluation.

simonwittber at gmail.com simonwittber at gmail.com
Tue Jan 17 20:56:46 EST 2006


Recently, I needed to provide a number of game sprite classes with
references to assorted images.

I needed a class to:
    - allow instances to specify which image files they need.
    - ensure that a name should always refer to the same image.
    - only load the image if it is actually used.

After some messing about, I came up with this:


class LazyBag(object):
    def __init__(self, function):
        self.__dict__["function"] = function
        self.__dict__["arguments"] = {}

    def __setattr__(self, key, args):
        try:
            existing_value = self.arguments[key]
        except KeyError:
            existing_value = args
        if existing_value != args:
            raise ValueError("Attribute must retain its initial value,
which is %s." % str(self.arguments[key]))
        self.arguments[key] = args

    def __getattr__(self, key):
        args = self.arguments[key]
        r = self.__dict__[key] = self.function(*self.arguments[key])
        del self.arguments[key]
        return r


This class lets me do something like this:

cache = LazyBag(Image.open)

cache.pic_1 = "data/pic_1.png"
cache.pic_2 = "data/pic_2.png"


Now, when the pic_1 and pic_2 attributes are accessed, they will return
an Image instance, which is something different to which they were
initially assigned. Is this kind of behavior bad form? Likewise, what
do people think about raising an exception during an assignment
operation?

Is there a correct name for this sort of class? 'LazyBag' doesn't sound
right...


-Sw.




More information about the Python-list mailing list