0

I understand that the best way to call a method in a superclass in python is to wirte:

class Foo(Bar):
    def foo(self):
        ...
        super(Foo, self).foo()
        ...

However, this means that if I change the name of the class Foo or I cut and paste the code in another class I have to remember to change the line that calls the method in the super class. Is there any way to get around this? At a minimum is annoying, at worst is very error prone.

Pedro Werneck
  • 40,902
  • 7
  • 64
  • 85
gae123
  • 8,589
  • 3
  • 35
  • 40
  • 1
    **don't** copy and paste your code to another class – Roman Bodnarchuk Apr 21 '12 at 20:46
  • possible duplicate of [How to call a parent class's method from child class in python?](http://stackoverflow.com/questions/805066/how-to-call-a-parent-classs-method-from-child-class-in-python) – AJ. Apr 21 '12 at 20:53
  • I wrote "cut & paste" not "copy & paste", there is a difference – gae123 Apr 23 '12 at 04:30
  • @AJ This is certanly *not* a duplicate of that Q. The other question is how to avoid typing the parent class, this is about typing the name of the class itself. – Steinar Lima Apr 11 '14 at 18:47

2 Answers2

1

In Python 3 you can write super() and it will fill in the class for you.

In Python 2 you need to write the name of the class. But changing the names of classes isn't exactly a common operation, so I don't really see that as much of a hardship. You just need to remember to search-and-replace for the name of the class if you change it -- but then you'll probably have to do that anyway, because its subclasses will refer to it by name as well.

gae123
  • 8,589
  • 3
  • 35
  • 40
Katriel
  • 120,462
  • 19
  • 136
  • 170
0

You mean easy, safe and easily understandable way for everyone (as far as super() goes)?

Short answer: no.

Long answer: yes. There are several ways to do it. One of them is using a metaclass to automate super() creation during class initialization.

>>> class AutoSuper(type):
...     def __init__(cls, name, bases, dict):
...         super(AutoSuper, cls).__init__(name, bases, dict)
...         setattr(cls, '_%s__super'%name, super(cls))
... 
>>> 

So, the super() call to the class being created is assigned to the __super attribute. The name mangling has to be done manually, but the instances and subclasses will hit it accordingly. Now you don't even have to call super, just use the __super attribute.

>>> class A(object):
...     __metaclass__ = AutoSuper
...     def m(self):
...         print 'A'
... 
>>> 
>>> class B(A):
...     def m(self):
...         print 'B'
...         self.__super.m()
... 
>>> 
>>> class C(B):
...     def m(self):
...         print 'C'
...         self.__super.m()
... 
>>> obj = C()
>>> obj.m()
C
B
A
>>> 

Of course, I'm posting this for learning purposes only, I don't recommend using it. This is the kind of thing that borders on the excess of cleverness that some condemn in Python.

Pedro Werneck
  • 40,902
  • 7
  • 64
  • 85