Reputation: 22668
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
Reputation: 17713
The BDFL agrees. In Python 3.0, support for super()
with no arguments was added:
PEP 3135: New
super()
. You can now invokesuper()
without arguments and (assuming this is in a regular instance method defined inside aclass
statement) the right class and instance will automatically be chosen. With arguments, the behavior ofsuper()
is unchanged.
Also see Pep 367 - New Super for Python 2.6.
Upvotes: 7
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
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
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