Circular references (was: Defining VCL-like framework for Py
Gordon McMillan
gmcm at hypernet.com
Fri May 21 23:44:31 EDT 1999
Alexander Staubo wrote:
> ... It might be nice if you could write a
> collection type of object which did not "own" its references. Same
> thing with parent/child relationships.
You can check out
http://www.handshake.de/~dieter/weakdict.html
(I've never tried it).
> Weak references can be implemented in several ways -- proxy objects
> and notifications, for instance.
> I don't know Python's internals well, but basically a proxy object
> would (1) have to pass through all calls to its actual object,
That's __getattr__ & __setattr__
> (2) it must not have a direct reference to its actual object, and
No, but somebody has to, or it will go away too soon.
> (3) its __del__ method would call the deletion method.
id(obj) returns a string guaranteed not to change while the object
lives. So use a dict (probably at module level) keyed by those ids,
paired with the object. The parent knows the id of the child. The
parent's __del__ method does "del dict[childid]".
If you really want to make it look transparent, the proxy object
object can have 2 attributes: dict and childid.
> As far as I
> can see, such a mechanism must be implemented in the Python core,
> since a proxy must be able to know when its object dies.
The only non-transparent thing here is the "proxy(d,c)", which can
certainly be hidden in the parent.
--WRProxy.py--------------------------
class proxy:
def __init__(self, dict, obj):
self.__dict__['dict'] = dict
self.__dict__['objid'] = id(obj)
dict[self.objid] = obj
def __getattr__(self, nm):
return getattr(self.dict[self.objid], nm)
def __setattr__(self, nm, value):
setattr(self.dict[self.objid], nm, value)
def __del__(self):
del self.dict[self.objid]
class P:
def __init__(self):
self.children = []
def mthd(self):
for child in self.children:
child.mthd()
def __del__(self):
print "P deleted"
class C:
def mthd(self):
print "Hello from a C"
def __del__(self):
print "C deleted"
def test():
d = {}
p = P()
c = C()
p.children.append(proxy(d,c))
p.mthd()
test()
print "That's all"
--------------------------
C:\TEMP>python WRProxy.py
Hello from a C
P deleted
C deleted
That's all
- Gordon
More information about the Python-list
mailing list