1

オブジェクトコレクションプロキシを作成しようとしています。これにより、次のようなことができます。

class A:
    def do_something():
        # ...

class B:
    def get_a():
        return A()

class Proxy:
    ?

collection = [B(), B()]
proxy = Proxy(collection)

proxy.get_a().do_something()
# ^ for each B in collection get_a() and do_something()

これを達成するための最良のアーキテクチャ/戦略は何でしょうか?

重要な質問は、get_a()の結果をキャッシュして、do_something()をプロキシできるようにする方法だと思います。

NB私はproxy.get_a().do_something()賢明なものを返すことを期待していません、それは物事をすることになっているだけです。

4

2 に答える 2

3

十分に単純です...さらにチェックを行うためにそれを適応させたいかもしれません

class A(object):
    def do_something(self):
        print id(self), "called"

class B(object):
    def get_a(self):
        return A()

class Proxy(object):
    def __init__(self, objs):
        self._objs = objs

    def __getattr__(self, name):
        def func(*args, **kwargs):
            return Proxy([getattr(o, name)(*args, **kwargs) for o in self._objs])
        return func

collection = [B(), B()]

proxy = Proxy(collection)
proxy.get_a().do_something()

結果:

4455571152 called
4455571216 called
于 2012-11-24T22:53:42.157 に答える
2

これについて最もPython的な方法は、おそらくリスト内包表記でしょう。

results = [b.get_a().do_something() for b in collection]

への呼び出しをキャッシュする場合は、メモ化B.get_a()を使用できます。自分でメモ化を行う簡単な方法は、次のようになります。

cache = None

# ...

class B:
    def get_a(self):
        global cache
        if cache is None:
            cache = A()
        return cache

複数の場所でキャッシュを使用する場合は、キーを区別するためにキーに基づいて結果をキャッシュする必要があります。便宜上、結果をキャッシュする関数を単純にラップできるデコレータを作成します。

この良い例は、Pythonアルゴリズム:Python言語での基本的なアルゴリズムの習得この質問を参照)にあります。関数の引数ではなく関数名をキャッシュキーとして使用するように変更すると、次のようになります。

from functools import wraps

def memoize(func):
    cache = {}
    key = func.__name__
    @ wraps(func)
    def wrap(*args):
        if key not in cache:
            cache[key] = func(*args)
        return cache[key]
    return wrap

class A:
    def do_something(self):
        return 1

class B:
    @memoize
    def get_a(self):
        print "B.get_a() was called"
        return A()


collection = [B(), B()]

results = [b.get_a().do_something() for b in collection]
print results

出力:

B.get_a() was called
[1, 1]
于 2012-11-24T21:54:35.473 に答える