4

Class definition:

class A(object):
    def foo(self):
        print "A" 


class B(object):
    def foo(self):
        print "B" 


class C(A, B): 
    def foo(self):
        print "C"

Output:

>>> super(C)
<super: <class 'C'>, NULL>
>>> super(C).foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'foo'

What is the use of super(type) if we can't access attributes of a class?

dspjm
  • 5,473
  • 6
  • 41
  • 62

3 Answers3

8

super(type) is an "unbound" super object. The docs on super discuss that, but don't really elaborate what an "unbound" super object is or does. It is simply a fact of the language that you cannot use them in the manner you are attempting to use them.

This is perhaps what you want:

>>> super(C, C).foo is B.foo
True

That said, what good is an unbound super object? I had to look this up, myself, and found a decent answer here. Note however, that the article's conclusion is that unbound super is a language wart, has no practical use, and should be removed from the language (and having read the article, I agree). The article's explanation on unbound super starts with:

Unbound super objects must be turned into bound objects in order to make them to dispatch properly. That can be done via the descriptor protocol. For instance, I can convert super(C1) in a super object bound to c1 in this way:

>>> c1 = C1()
>>> boundsuper = super(C1).__get__(c1, C1) # this is the same as super(C1, c1)

So, that doesn't seem useful, but the article goes on:

Having established that the unbound syntax does not return unbound methods one might ask what its purpose is. The answer is that super(C) is intended to be used as an attribute in other classes. Then the descriptor magic will automatically convert the unbound syntax in the bound syntax. For instance:

>>> class B(object):
...     a = 1
>>> class C(B):
...     pass
>>> class D(C):
...     sup = super(C)
>>> d = D()
>>> d.sup.a
1

This works since d.sup.a calls super(C).__get__(d,D).a which is turned into super(C, d).a and retrieves B.a.

There is a single use case for the single argument syntax of super that I am aware of, but I think it gives more troubles than advantages. The use case is the implementation of autosuper made by Guido on his essay about new-style classes.

The idea there is to use the unbound super objects as private attributes. For instance, in our example, we could define the private attribute __sup in the class C as the unbound super object super(C):

>>> C._C__sup = super(C)

But do note that the article continues to describe the problems with this (it doesn't quite work correctly, I think mostly due to the fact that the MRO is dependent on the class of the instance you are dealing with, and thus given an instance, some class X's superclass may be different depending on the instance of X we are given).

Community
  • 1
  • 1
Thanatos
  • 42,585
  • 14
  • 91
  • 146
  • +1. I think it's worth mentioning up front the main take-home message of that blog post, namely that unbound super objects have very little practical use. This is basically the answer to the OP's question. – BrenBarn Mar 21 '14 at 04:46
  • @BrenBarn I've attempted to make the article's point about the practical use of super more visible. – Thanatos Mar 21 '14 at 04:49
2

To accomplish what you want, you need to call it like this:

>>> myC = C()
>>> super(C,myC).foo()
A
Tyler
  • 17,669
  • 10
  • 51
  • 89
1

Note that there is a NULL reference to some object. It basically needs a class and an instance of a related object for it to function.

>>> super(C, C()).foo
<bound method C.foo of <__main__.C object at 0x225dc50>>

See: Understanding Python super() with __init__() methods for more details.

Community
  • 1
  • 1
metatoaster
  • 17,419
  • 5
  • 55
  • 66