2

オブジェクトを別のオブジェクトのプロパティに割り当てる場合、最初のオブジェクトに2番目のオブジェクトを指定する自然な方法は何ですか?これは、データベースで外部キーが行うことと似ていると思います。

class Box(object):
    things = []

class Thing(object):
    box = None

thing = Thing()
box = Box()

# thing.box updates the box.things
thing.box = box
thing in box.things # should be true

# box.things updates thing.box
box.things.append(thing)
thing.box == box # should be true

これも1対1、多対多の関係で実現したいと思います。これは可能ですか?

私は現在、すべての「もの」のグローバルなコレクションを保持し、次に「ボックス」にプロパティを提供して、1つの場所にのみ属するものに属するものの情報を提供しています。ただし、モノのコレクションは非常に大きいので、「ボックス」オブジェクト自体に「モノ」オブジェクトへのポインタを配置したいと思います。

4

3 に答える 3

1

「もの」の場合、単一のオブジェクトのみを追跡したい場合、Pythonのプロパティはそのままで機能します。

多くの「モノ」のコンテナに関しては、単一のプロパティは機能しません。オブジェクトの属性を指すコンテナへの変更を追跡する必要があるためです(プロパティは属性自体の変更に対して機能します)。したがって、コンテナに追加されるオブジェクトに必要な変更を加える小さなカスタムコンテナクラスは、簡単な方法です。(リストよりも「セット」の方が良いと思います)

class Thing(object):
    def get_box(self):
        return self._box
    def set_box(self, box):
        self._box = box
        if not self in box.things:
            box.things.add(self)
    box = property(get_box, set_box)

class CallbackSet(set):
    def __new__(cls, box, *args, **kw):
        self = set.__new__(cls, *args, **kw)
        self.box = box
    def add(self, item):
        item.box = self.box
        return set.add(self, item)

class Box(object):
    def __init__(self):
        self.things = CallbackSet(self)
于 2012-05-15T23:09:47.860 に答える
0

おそらくpythonweakrefを使用することをお勧めします。そうしないと、循環参照が発生し、ガベージコレクター(メモリリーク)に問題が発生する可能性があります。

最も重要な質問は、オブジェクトを強力な参照(ガベージコレクションを防ぐオブジェクト)を誰が保持するかです。それは「ワールド」オブジェクトですか、それとも「ボックス」オブジェクトですか。ボックスオブジェクトを保持しているのは誰ですか?それ以外は、他のすべての人が他のすべての人に対して弱い参照を保持します。または、 python id()で全員を参照することもできますが、intとstringsで使用する場合は注意が必要です(使用する場合a=a+1 id(a)は変更されます)。weakrefドキュメントの最後にあるアイデアを探してください。

必要な構文を実装するには、コンテナタイプのエミュレートを見てください。

于 2012-05-15T22:26:46.777 に答える
0

これは、次のような記述子の目的です。

class Box(object):

    things = []


class BoxManager(object):

    def __set__(self, instance, value):
        if isinstance(value, Box):
            instance._box = value
            Box.things.append(instance)

    def __get__(self, instance, type_=None):
        return instance._box


class Thing(object):
    box = BoxManager()


thing = Thing()
box = Box()

# thing.box updates the box.things
thing.box = box
print 'Thing is in box.things', thing in box.things  # should be true

# box.things updates thing.box
box.things.append(thing)
thing.box == box  # should be true
print 'thing.box == box is', thing.box == box

import pdb
pdb.set_trace()
于 2012-05-16T22:50:15.430 に答える