、変更が発生したときに通信できる要素と、そのコレクションの間にいくつかの接続がなければなりません。このため、インスタンスをコレクションにバインドするか、コレクションの要素をプロキシして、変更通信が要素のコードに漏れないようにする必要があります。
私が提示しようとしている実装についての注意点、プロキシ方法は、メソッドの内部ではなく直接設定によって属性が変更された場合にのみ機能します。もっと複雑な帳簿システムが必要になるでしょう。
また、それはあなたがオブジェクト上__setattr__
へをオーバーライドすることができますインデックスが代わりにlist
from collections import defaultdict
class Proxy(object):
def __init__(self, proxy, collection):
self._proxy = proxy
self._collection = collection
def __getattribute__(self, name):
if name in ("_proxy", "_collection"):
return object.__getattribute__(self, name)
else:
proxy = self._proxy
return getattr(proxy, name)
def __setattr__(self, name, value):
if name in ("_proxy", "collection"):
object.__setattr__(self, name, value)
else:
proxied = self._proxy
collection = self._collection
old = getattr(proxied, name)
setattr(proxy, name, value)
collection.signal_change(proxied, name, old, value)
class IndexedCollection(object):
def __init__(self, items, index_names):
self.items = list(items)
self.index_names = set(index_names)
self.indices = defaultdict(lambda: defaultdict(set))
def __len__(self):
return len(self.items)
def __iter__(self):
for i in range(len(self)):
yield self[i]
def remove(self, obj):
self.items.remove(obj)
self._remove_from_indices(obj)
def __getitem__(self, i):
# Ensure consumers get a proxy, not a raw object
return Proxy(self.items[i], self)
def append(self, obj):
self.items.append(obj)
self._add_to_indices(obj)
def _add_to_indices(self, obj):
for indx in self.index_names:
key = getattr(obj, indx)
self.indices[indx][key].add(obj)
def _remove_from_indices(self, obj):
for indx in self.index_names:
key = getattr(obj, indx)
self.indices[indx][key].remove(obj)
def signal_change(self, obj, indx, old, new):
if indx not in self.index_names:
return
# Tell the container to update its indices for a
# particular attribute and object
self.indices[indx][old].remove(obj)
self.indices[indx][new].add(obj)
オブジェクトがすでに両方を持っているのに、なぜあなたは '<、オブジェクトをタイムスタンプ>' <ステータス、オブジェクト> 'と'の辞書を作成することになり見ています属性? –
高速アクセス用のインデックスが必要です。たとえば、ステータス3のオブジェクトを取得したいとします。 –
複数のオブジェクトのステータスまたはタイムスタンプが似ているとどうなりますか? –