Search code examples
pythoninheritancesuperclass

Are there any potential issues with setting super() to a class attribute?


I've slightly changed the way I use super as I've got a little more familiar with it, and each time I've found an issue. I'm still having to use Python 2.7 so the old syntax is necessary.

Two of the alternate ways I've tried and stopped using are super(self.__class__, self) and InheritClass.func(self, ...).

I realised that super basically returns an object, so instead of constantly creating the object, it could be assigned to a class attribute instead. It seems a little neater as the instance is only needed to be read once, but would there be any potential issues arising over this.

I've been setting it to self.__super so nothing can really interfere with it, I'd just like an opinion before I do too much and have to rewrite a whole load of code.


Solution

  • The problem with assigning a super object to an instance attribute is that it creates a reference cycle:

    import weakref
    
    class RefCycle(object):
        def __init__(self):
            self.__super = super(RefCycle, self)
    
    obj = RefCycle()
    
    ref = weakref.ref(obj)
    del obj
    assert ref() is None  # <- assertion fails, the object still exists
    

    Of course the garbage collector will detect and clean up this reference cycle eventually, but if you get into a habit of using super like this, you will be wasting a significant amount of memory.

    A better solution is to implement a property that returns a super object:

    class NoRefCycle(object):
        @property
        def __super(self):
            return super(NoRefCycle, self)
    

    This way, no reference cycles are created.