faber faber - 4 months ago 25
Python Question

Python __init__() how don't override important functionality?

I need to add another option in a class, a simple 'edit=False'. Whithout override completely init().
I found this piece of code written for kivy:

class TitleBox(BoxLayout):
def __init__(self, **kwargs):
# make sure we aren't overriding any important functionality
super(TitleBox, self).__init__(**kwargs)

But when I try to edit for my purposes I receive: "TypeError: init() takes at most 2 arguments (3 given)"

class Person_Dialog(tkSimpleDialog.Dialog):
def __init__(self, edit=False, **kwargs):
super(Person_Dialog, self).__init__(**kwargs)
self.edit = edit


Given an __init__ signature of:

def __init__(self, edit=False, **kwargs):

When you do this:

add = Person_Dialog(root, 'Add person')

Python creates an instance and assigns it to the self argument. Then it assigns root to the edit argument. Then it takes 'Add a person' and finds no other positional arguments to assign it to.

To fix this add another argument to __init__:

class Person_Dialog(tkSimpleDialog.Dialog):
    def __init__(self, parent, edit=False, **kwargs): # added parent argument
        super(Person_Dialog, self).__init__(parent, **kwargs)
        self.edit = edit

Note that we also pass parent to the superclass because tkSimpleDialog.Dialog has this signature __init__(self, parent, title=None).

Unfortunately, your code now fails with TypeError: must be type, not classobj because tkSimpleDialog.Dialog is an old style class and you can't use super() with old style classes. (Python 3 does away with old style classes, so you won't have this issue there.)

So to fix this replace the call to super() with a direct reference to the superclass:

class Person_Dialog(tkSimpleDialog.Dialog):
    def __init__(self, parent, edit=False, **kwargs):
        # referencing the superclass directly
        tkSimpleDialog.Dialog.__init__(self, parent, **kwargs) 
        self.edit = edit

Now your code will work.