04 8月 2011

[Python] Lazy initialization

在寫大型的Project時,應該都會遇到一種痛,就是AP開起來的速度"操級慢",很多人習慣在一開始就把一些用不到的變數initial起來,不但影響到AP launch的速度,也會讓memory吃得肥茲茲的。

所以就有人嘗試在一開始將變數initial成None,等到要用時再判斷是不是None,是的話再真正的initial這個變數。

不過這種作法,可能會讓code變得稍微複雜一點,參考一下別人的作法,其實有更好的方法來實作這種Lazy Initialization,就是用到Python的decorator+property!


def lazyproperty(func):
    ''' 
    Lazy initialization - Design Pattern
    Implement it by property
    
    Usage - 
        class Foo(object):
            def __init__(self):
                super(Object,self).__init__()
            @lazyproperty
            def sum(self):
                _sum = 0
                for i in range(100):
                    _sum += i
                return _sum
        o = Foo()
        print o.sum
    
    Information -
        the setter raise exception only if the class inhert from object!
    '''
    attr = '_lazy'.join( func.__name__ )
    def get_lazyval(self):
        if not hasattr(self, attr):
            setattr(self, attr, func(self))
        return getattr(self, attr)
    def set_lazyval(self, v):
        raise AttributeError('The lazy property is read-only')
    return property(get_lazyval, set_lazyval)
透過這個方式,等到get這個instance的變數時,才會執行init function裡的事,只是,如果希望set有exception的話,必須要讓class繼承object才有基本property的功能。

Reference :

沒有留言: