Samuele Pedroni pedronis at
Thu Feb 27 13:16:54 CET 2003

> So, object <class '__main__.Sub'> cannot be deleted because of
> this reference to it.  Exactly where this tuple comes from is
> an interesting puzzle (I think it's object keeping track of all
> of its subclasses, but that's just a guess),

yes, but it politely uses weakrefs, see below

> but in practice I
> do think it means no class object is ever truly deleted...

no, I have modifed slightly the code:

import sys

class MyMetaclass(type):

    def __init__(cls, name, bases, dict):
        super(MyMetaclass, cls).__init__(name, bases, dict)
        print 'initialized', cls.__name__

    def __del__(cls):
        print 'deleted', cls.__name__

class MyClass(object):
    if len(sys.argv)>1 and sys.argv[1]=='meta':
     __metaclass__ = MyMetaclass

class Sub(MyClass):

del Sub

import gc,pprint

gc.collect() # force involved weak-refs to be cleared

print "MyClass subclasses",MyClass.__subclasses__()
print "garbage",gc.garbage

def isActuallySub(x):
    return type(x) is MyMetaclass and x is not MyClass
a = [x for x in gc.get_objects() if isActuallySub(x)]
del x

if not a:
    print "Sub not held"
    referrers = [x for x in gc.get_referrers(a[0]) if x is not a]

    print len(referrers),'still holding on to Sub...:'


MyClass subclasses []
garbage []
Sub not held

here all is good.

C:\exp\py-subclasses-gc>\transit\Py23\python meta
initialized MyClass
initialized Sub
MyClass subclasses [<class '__main__.Sub'>]
garbage [<class '__main__.Sub'>]
4 still holding on to Sub...:
[[<class '__main__.Sub'>],
 (<class '__main__.Sub'>, <class '__main__.MyClass'>, <type 'object'>),
 <attribute '__dict__' of 'Sub' objects>,
 <attribute '__weakref__' of 'Sub' objects>]

so we have a cycle involving __del__s ??? Sub and MyMetaclass form a cycle
but it be breaked by weak-refs??? this merits further study...

More information about the Python-list mailing list