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

我还想通过一对一和多对多的关系来实现这一点。这可能吗?

此刻我一直保存着所有“东西”的全局集合,然后在“盒子”上提供一个属性,让属于什么的信息只在一个地方。然而,事物的集合是如此巨大,以至于我想将指向“事物”对象的指针放在“盒子”对象本身中。

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

这就是描述符的用途,如下所示:

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 回答
0

您可能想要使用python weakref。否则你最终会得到循环引用,这可能会导致垃圾收集器出现问题,也就是内存泄漏。

最重要的问题是,谁将持有对象的强引用(阻止它被垃圾收集的那个)。它是“世界”对象还是“盒子”对象?谁持有盒子对象?除此之外,所有其他人都会对其他人持有弱引用。或者你可以通过它的python id()来引用每个人,但是在使用 int 和字符串时要小心(如果你这样做a=a+1 id(a)会改变)。在弱引用文档的末尾寻找想法。

要实现您想要的语法,请查看emulating container types

于 2012-05-15T22:26:46.777 回答