This question already has answers here:
Understanding Python super() with __init__() methods [duplicate]
(7 answers)
Closed 2 years ago.
I have a question about classes, subclasses and inheritance in Python.
I've been using Tkinter for GUI development for some time and have decided to learn how to use Kivy. In the Kivy documentation I came across a line of code that didn't make any sense to me. It is as follows (note, GridLayout is a class I imported from the kivy module):
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
The super call on LoginScreen and self instead of GridLayout really confuses me! Is the class inheriting itself? What is going on?
In Tkinter I would write something like (note again that, tk.Frame is a class imported from the Tkinter module):
class LoginScreen(tk.Frame)
def __init__(self, parent):
super().__init__(parent)
As I typed out these two examples I noticed that I am not passing anything into super(). Are the default parameters of the super method the name of the class and self? i.e. is the above akin to writing...
class LoginScreen(tk.Frame):
def __init__(self, parent):
super(LoginScreen, self).__init__(parent)
If they are different can you explain why they are different, but if they are the same can you explain a little more in-depth as to how super() does what it does (beyond simply it inherits the methods and attributes of the parent class)?
Yes, these are the default parameters to super as you can see in the example from the docs:
class C(B):
def method(self, arg):
super().method(arg) # This does the same thing as:
# super(C, self).method(arg)
(the comment is not mine, it appears like this in the original example)
Related
This question already has answers here:
using super without inheritance class in python3
(3 answers)
Closed 2 years ago.
I was looking at a code which a Parent class calls super:
class ParentClass:
def __init__(self):
super(ParentClass, self).__init__()
I don't understand why would someone call super on itself and how does this not get stuck on a recursive loop. Is there something in the background of Python mechanisms that I'm missing?
In python, all classes are implicitly a subclass of object. super will always follow a Method Resolution Order (mro) to determine which function to call. This is explained well in the super docs.
So, for a class like-
class ParentClass:
def __init__(self):
super(ParentClass, self).__init__()
The mro follows - ParentClass -> object
Which means super(ParentClass, self) (or the shorthand, super()) translates to object and object.__init__() is indeed a very valid call.
I've noticed that a lot of people pass the child class to the call to the parent constructed:
class ChildClass(ParentClass):
def __init__(self, *args):
super(ChildClass, self).__init__()
But sometimes I see this:
class ChildClass(ParentClass):
def __init__(self, *args):
super().__init__()
Where nothing is passed to the parent constructor.
So far, every time I see the first method in some code I want to use, I've been able to replace it with the second method with no problems. I'm wondering if I can just use the second way universally?
The super() function is used to give access to methods and properties of a parent or sibling class.
The super() function returns an object that represents the parent class.
If you have python v3, its okay to not pass any arguements to the super function. However, if you python v2, you need to arguements.
Syntax for python 3 -
super().methoName(args)
Syntax for older versions-
super(subClass, instance).method(args)
This question already has answers here:
Understanding Python super() with __init__() methods [duplicate]
(7 answers)
Closed 6 years ago.
class MyObject1(object):
def __init__(self):
super(MyObject1, self).__init__()
pass
class MyObject2(object):
def __init__(self, arg):
super(MyObject2, self).__init__()
pass
I have read a python27 code like this,
I know 'super' means father class constructor function,
but I cannot understand why these two classes call themselves' constructor function '__init__',
it seems don't have any practical effect.
These are some pretty basic OO methods in Python. Read here.
super and self are similar:
super() lets you avoid referring to the base class explicitly, which
can be nice. But the main advantage comes with multiple inheritance,
where all sorts of fun stuff can happen. See the standard docs on
super if you haven't already.
(from this answer)
Here's an example of super in action:
class Animal(object):
def __init__(self, speed, is_mammal):
self.speed = speed
self.is_mammal = is_mammal
class Cat(Animal):
def __init__(self, is_hungry):
super().__init__(10, True)
self.is_hungry = is_hungry
barry = Cat(True)
print(f"speed: {barry.speed}")
print(f"is a mammal: {barry.is_mammal}")
print(f"feed the cat?: {barry.is_hungry}")
You can see that super is calling the base class (the class that the current class inherits), followed by an access modifier, accessing the base class' .__init__() method. It's like self, but for the base class.
Using python 2.7 with new class style, if my class inherits from Objectclass, what is the behavior of super(ClassName, self).__init__() ? What I mean is, what happens behind the scenes ? What is the difference if I omitted it ?
An example above:
class ClassName(object):
"""docstring for ClassName"""
def __init__(self, arg):
super(ClassName, self).__init__() ## The question above is about this super
self.arg = arg
class OtherClass(ClassName):
"""docstring for OtherClass"""
def __init__(self, arg, otherArg):
super(OtherClass, self).__init__(arg) ## The question below is about this super
self.otherArg = otherArg
If I omit the super, what is the happens behind the scenes ?
Thanks.
In the case of single inheritance, absolutely nothing. object.__init__() does squat.
In the case of multiple inheritance, one entire chain of initialization is not called. What this does to your application varies, but it's generally not a good thing to happen.
I want to define several plugins.
They all inherit from the superclass Plugin.
Each plugin consists on a wx.Panel that have a more specific method called "draw".
How can I define a class as a Panel and afterwards call that class in my frame?
I've tried like this:
class Panel(wx.Panel):
def __init__(self, parent):
wx.Panel(self, parent)
but it gives me this error:
in __init__
_windows_.Panel_swiginit(self,_windows_.new_Panel(*args, **kwargs))
TypeError: in method 'new_Panel', expected argument 1 of type 'wxWindow *'
Thanks in advance!
class MyPanel(wx.Panel):
def __init__(self, *args):
wx.Panel.__init__(self, *args)
def draw(self):
# Your code here
There is a class wx.PyPanel that is a version of Panel intended to be subclassed from Python and allows you to override C++ virtual methods.
There are PyXxxx versions of a number of other wx classes as well.
How can I define a class as a Panel and afterwards call that class in my frame?
What you tried is close, but you're not properly calling the super class __init__. When subclassing wxPython classes, however, it's generally best to use the following pattern so that you don't have to worry about which specific arguments you are passing to it. (This wouldn't have solved your problem, which was outside of the code in question, but it maybe makes it clearer what's happening.)
class Panel(wx.Panel):
def __init__(self, *args, **kwargs):
wx.Panel.__init__(self, *args, **kwargs)
# ... code specific to your subclass goes here
This ensures that anything passed in is handed on to the super class method with no additions or removals. That means the signature for your subclass exactly matches the super class signature, which is also what someone else using your subclass would probably expect.
If, however, you are not actually doing anything in your own __init__() method other than calling the super class __init__(), you don't need to provide the method at all!
As for your original issue:
but it gives me this error: in __init__ windows.Panel_swiginit(self,windows.new_Panel(*args, **kwargs)) TypeError: in method 'new_Panel', expected argument 1 of type 'wxWindow *'
(Edited) You were actually instantiating a wx.Panel() inside the __init__ rather than calling the super class __init__, as Javier (and Bryan Oakley, correcting me) pointed out. (Javier's change of the "parent" arg to "*args" confused me... sorry to confuse you.)