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