airportyh
airportyh

Reputation: 22668

Why do I have to specify my own class when using super(), and is there a way to get around it?

When using Python's super() to do method chaining, you have to explicitly specify your own class, for example:

class MyDecorator(Decorator):
    def decorate(self):
        super(MyDecorator, self).decorate()

I have to specify the name of my class MyDecorator as an argument to super(). This is not DRY. When I rename my class now I will have to rename it twice. Why is this implemented this way? And is there a way to weasel out of having to write the name of the class twice(or more)?

Upvotes: 17

Views: 2984

Answers (4)

Peter Rowell
Peter Rowell

Reputation: 17713

The BDFL agrees. In Python 3.0, support for super() with no arguments was added:

PEP 3135: New super(). You can now invoke super() without arguments and (assuming this is in a regular instance method defined inside a class statement) the right class and instance will automatically be chosen. With arguments, the behavior of super() is unchanged.

Also see Pep 367 - New Super for Python 2.6.

Upvotes: 7

nosklo
nosklo

Reputation: 222862

In Python 3.0, you can use super() which is equivalent to super(ThisClass, self).

Documentation here. Code sample from the documentation:

class C(B):
    def method(self, arg):
        super().method(arg)    
        # This does the same thing as: super(C, self).method(arg)

Upvotes: 12

fans656
fans656

Reputation: 305

This answer is wrong, try:

def _super(cls):
    setattr(cls, '_super', lambda self: super(cls, self))
    return cls

class A(object):
    def f(self):
        print 'A.f'

@_super
class B(A):
    def f(self):
        self._super().f()

@_super
class C(B):
    def f(self):
        self._super().f()

C().f() # maximum recursion error

In Python 2 there is a way using decorator:

def _super(cls):
    setattr(cls, '_super', lambda self: super(cls, self))
    return cls

class A(object):
    def f(self):
        print 'A.f'

@_super
class B(A):
    def f(self):
        self._super().f()

B().f() # >>> A.f

Upvotes: 4

Autoplectic
Autoplectic

Reputation: 7666

you can also avoid writing a concrete class name in older versions of python by using

def __init__(self):
    super(self.__class__, self)
    ...

Upvotes: -1

Related Questions