如果我将一个对象分配给另一个对象的属性,那么获得给定第二个对象的第一个对象的自然方法是什么?我认为这有点像外键在数据库中的作用。
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
我也希望通过一对一和多对多的关系实现这一目标。这可能吗?
我一直在保留所有“事物”的全球集合,然后在“盒子”上提供一个属性,以便所有属于仅在一个地方的信息。然而,事物的集合是如此巨大,我想把指针放在“盒子”对象本身的“事物”对象中。
答案 0 :(得分:1)
对于“东西”的情况,你只想跟踪一个单独的对象, Python的属性将为您提供开箱即用的功能。
对于许多“东西”的容器,单个属性不会 work - 因为您想跟踪指向对象属性的容器的更改 (属性适用于属性本身的更改)。因此,一个小的自定义容器类可以对要添加到容器的对象进行更改,这是一种简单的方法。 (我认为“套装”对你来说比列表更好)
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)
答案 1 :(得分:0)
您可能希望使用python weakref。否则,您将最终获得循环引用,这可能会导致垃圾收集器(即内存泄漏)出现问题。
最重要的问题是,谁将保持对象强引用(保持它不被垃圾收集的那个。)它是一个“世界”对象还是“盒子”对象?谁持有盒子对象?除此之外,所有其他人都会对其他人提供弱引用。或者你可以通过python id()来引用每个人,但是在使用int和字符串时要小心(如果你a=a+1
id(a)
已经改变了)。在weakref文档的末尾寻找想法。
要实现所需的语法,请查看emulating container types。
答案 2 :(得分: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()