ANN: mxProxy Package - Version 0.2.0

Neil Schemenauer nascheme at ucalgary.ca
Thu Aug 19 19:14:20 EDT 1999


M.-A. Lemburg <mal at lemburg.com> wrote:
>2. using a weak reference which allows you to build circular
>   reference models in your data without producing the other-
>   wise difficult to handle memory leakage induced by this.

This is an interesting implementation of weak references.
Thanks.  Attached is a weak reference implementation I cooked up
yesterday.  It is more of a hack then your approach but has the
advantage that referenced objects die sooner.  Unfortunately, my
proxy object is incomplete.

    Neil


"""
Weak References in Python

This is a hack.  It works okay in the current version of CPython.  Any object
that has settable attributes can have weak references to it.  To get a weak
reference to an object use WeakRef(object).  When the object is destroyed any
attempts to access it though the weak reference will raise an exception.  

This module requires the refhack extension module, available from:

    http://www.ucalgary.ca/~nascheme/python/

Neil Schemenauer <nascheme at ucalgary.ca>
August, 1999
"""

import refhack

# something that cannot conflict with normal Python code
MAGIC_NAME = ' __weakref_cleaner'

WeakRefError = 'WeakRefError'

class WeakRef:
    """Create a weak reference and return a proxy object"""
    def __init__(self, obj):
        self._alive = 1
        self._obj = obj
        if not hasattr(self._obj, MAGIC_NAME):
            cleaner = WeakRefCleaner(self._obj)
        else:
            cleaner = getattr(self._obj, MAGIC_NAME)
        cleaner.add_ref(self)
        refhack.decref(self._obj)

    def _destroy(self):
        if self._alive:
            # _obj is now gone, don't touch it.  The refcount of _obj will go
            # negitive but this is okay in the current Python implementation
            self._alive = 0

    def __getattr__(self, name):
        if not self._alive:
            raise WeakRefError, 'object has been destroyed'
        return getattr(self.__dict__['_obj'], name)

    #def __setattr__(self, name, value):
    #    if not self._alive:
    #        raise WeakRefError, 'object has been destroyed'
    #    self.__dict__['_obj'].setattr(name, value)


class WeakRefCleaner:
    """A little object to die with the weak referenced object.  It
    will inform all weak references of the objects death"""
    def __init__(self, obj):
        self.refs = []
        # the object must have settable attributes
        setattr(obj, MAGIC_NAME, self)

    def add_ref(self, ref):
        self.refs.append(ref)

    def remove_ref(self, ref):
        self.refs.remove(ref)

    def __del__(self):
        for ref in self.refs:
            ref._destroy()


def test():
    class A:
        pass
    a = A()
    a.b = 1
    r = WeakRef(a)
    print r.b
    del a
    print r.b

if __name__ == '__main__':
    test()




More information about the Python-list mailing list