資源を共有するインスタンスを作るデコレータの作成

キャッシュを共有したい。資源の共有とかバグになりやすいところだけれど。
キャッシュを共有できた方が効率が良いので作ってみる。
sharedというデコレータを書いた。
これは引数に渡された名前の属性を共有するインスタンスを生成する。duplicateというメソッドを追加する。

def shared(*attrs):
    """resorceの共有をする機能を付加するデコレータ
    """
    def decorated(cls):
        def purge(self):
            return ((k, getattr(self, k)) for k in attrs)

        def duplicate(self, *args, **kwargs):
            another = cls(*args, **kwargs)
            for name, val in self.purge():
                setattr(another, name, val)
            return another

        cls.purge = purge
        cls.duplicate = duplicate
        return cls
    return decorated
    
@shared("results")
class Cached(object):
    """渡された関数を使って値を取得するクラス。結果の履歴は保存される。
    """
    def __init__(self, seed):
        self.results = []
        self.seed = seed

    def get(self):
        val = self.seed()
        self.results.append(val)
        return val

実行例

cached1からcached2が作られる。両者がresultsの値を共有してくれれば良い。

import random
cached1 = Cached(lambda : random.randint(10, 100))
cached1.get()
cached1.get()
cached1.get()
cached2 = cached1.duplicate(lambda : random.randint(-100, -10))
cached2.get()
cached2.get()
print cached1.results
print cached2.results

# [15, 49, 96, -79, -42]
# [15, 49, 96, -79, -42]

できている。