3
\$\begingroup\$

Depending on the name of the first argument, self.__sup or cls.__sup behaves like super() in Python 3, while this code is written in Python 2.7. It works for both ordinary methods and class methods(static methods don't use super()). See my code for detailed examples:

class mySuper(object):
    def __init__(self, cls):
        self.cls = cls
    def __get__(self, obj, cls):
        if obj is None:
            return super(self.cls, cls)
        else:
            return super(self.cls, obj)

class Meta(type):
    def __init__(cls, name, bases, clsdict):
        setattr(cls, '_' + name + '__sup', mySuper(cls))
        super(Meta, cls).__init__(name, bases, clsdict)

# Usage examples:

class A(object):
    __metaclass__ = Meta
    def meth(self):
        print 'A.meth(%s)' % self
    @classmethod
    def clsmeth(cls):
        print 'A.clsmeth(%s)' % cls

class B(A):
    def meth(self):
        self.__sup.meth()                # super().meth()
        print 'B.meth(%s)' % self
    @classmethod
    def clsmeth(cls):
        cls.__sup.clsmeth()              # super().clsmeth()
        print 'B.clsmeth(%s)' % cls

class C(A):
    def meth(self):
        self.__sup.meth()
        print 'C.meth(%s)' % self
    @classmethod
    def clsmeth(cls):
        cls.__sup.clsmeth()
        print 'C.clsmeth(%s)' % cls

class D(B, C):
    def meth(self):
        self.__sup.meth()
        print 'D.meth(%s)' % self
    @classmethod
    def clsmeth(cls):
        cls.__sup.clsmeth()
        print 'D.clsmeth(%s)' % cls

d = D()
d.meth()
d.clsmeth()

Here is the output:

A.meth(<__main__.D object at 0x103c8aed0>)
C.meth(<__main__.D object at 0x103c8aed0>)
B.meth(<__main__.D object at 0x103c8aed0>)
D.meth(<__main__.D object at 0x103c8aed0>)
A.clsmeth(<class '__main__.D'>)
C.clsmeth(<class '__main__.D'>)
B.clsmeth(<class '__main__.D'>)
D.clsmeth(<class '__main__.D'>)

I'm sorry if the examples are not very meaningful, but I'm just a beginner. (Maybe emulating super() itself is pointless.)

Apart from the "Usage examples", it's just a little snippet, so please tell me any problem you can spot in this piece of code.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

First of all, +1 on the idea. Maybe you could submit this to the Python developers for Python 2.7.13 :)


Your super class is called mySuper. Oh, the sound of my in a variable name! Such are the names that are used when describing code to a non-programmer. We shouldn't allow that in real code. It is a Super class; that's all there is to it. If you were to keep my in there, however, it should be PascalCase, not mixedCase. (That is, MySuper, not mySuper). It should be thus for compliance with PEP 8, the Python style guide.


Why Meta? Well, obviously it is a meta class, but for what? The name should describe it more aptly. This happens to be an incredible meta class, so call it SuperMeta ;)


Instead of a couple concatenations, use string formatting:

setattr(cls, '_{}__sup'.format(name), Super(cls))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.