Wednesday, August 7, 2013

Onetime evaluation for Python object method

Following technique described in a previous post, another interesting problem can be solved.

I would like to delay object method evaluation until I access the method and I want to evaluate it only once.

In straight-forward approach, the following can be written:

class BigMath(object):
    def get_big_data(self):
        if hasattr(self, "_rv"):
            return self._rv
        self._rv = self._get_big_data()
        return self._rv
        
    def _get_big_data(self):
        print "working hard...."
        return 42
>>> m = d.BigMath()
>>> m.get_big_data()
working hard....
42
>>> m.get_big_data()
42
>>> 
Hard work is only done once as we can see. Additionally we can rename a get_big_data to big_data and make is property.

The above approach is simple and trivial. However reduplicating it from class to class and from method to method makes things boggy. I would like to have something reusable that I can apply on desired methods. Like this:

class BigMath(object):
    @OneTime
    def big_data(self):
        print "working hard...."
        return 42
Much more elegant, right? Now lets reveal that magic OneTime decorator.
class OneTime(object):
    def __init__(self, func):
        self.func = func

    def __get__(self, obj, cls):
        to_augment = obj or cls
        rv = self.func(to_augment)
        setattr(to_augment, self.func.__name__, rv)
        return rv
Its actually straight-forward if you are familiar with class-as-decorator technique:
  • Again, we create class that behaves both as decorator and descriptor
  • This is parameter-less decorator, so we need to implement only __init__ and not __call__
  • We records the method function
  • When method is accessed (i.e. __get__ gets invoked), we execute the function and cache its results by overriding ourselves.
Enjoy.

1 comment:

  1. Cults 3D is a large platform for creating, promoting, and buying 3D printer fashions. Whilst some fashions must be purchased, there are also 1000's of free 3D printer fashions to Luggage Sets download too. Getting started with 3D modeling and 3D printing can seem like a frightening task, but it doesn't have to be.

    ReplyDelete