Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass all arguments from __init__ to super class

IS there any magic I can use in Python to to effectively use super constructor by just adding some extra arguments?

Ideally I'd like to use something like:

class ZipArchive(zipfile.ZipFile):
    def __init__(self, verbose=True, **kwargs):
        """
        Constructor with some extra params.

        For other params see: zipfile.ZipFile
        """
        self.verbose = verbose
        super(ZipArchive, self).__init__(**kwargs)

And then be able to use the original constructor arguments mixed with some extra stuff from my class. Like so:

zip = ZipArchive('test.zip', 'w')
zip = ZipArchive('test.zip', 'w', verbose=False)

I'm using Python 2.6, but if the magic can only be achieved in higher version of Python then I'm interested too.

EDIT: I should probably mention that above doesn't work. The error is: TypeError: __init__() takes at most 2 arguments (3 given)

like image 280
Nux Avatar asked Jun 14 '13 10:06

Nux


People also ask

What does super () __ Init__ do?

When you initialize a child class in Python, you can call the super(). __init__() method. This initializes the parent class object into the child class. In addition to this, you can add child-specific information to the child object as well.

Can we pass parameter in super?

You can pass parameters (explicitly) to a constructor, including via super() , but that affects only the constructor directly being invoked, not (directly) any other constructor or method it invokes.

Is Super INIT called automatically?

If there are superclass [init] you want to call, you have to explicitly call them with super(). __init__() recursively. If there is no [init] defined along the tree path, nothing will be called. It is just an ordinary function that is automatically called once at construction time.

How does super () method play an important role in inheritance?

Python | super() in single inheritance At a fairly abstract level, super() provides the access to those methods of the super-class (parent class) which have been overridden in a sub-class (child class) that inherits from it.


1 Answers

You are almost there:

class ZipArchive(zipfile.ZipFile):
    def __init__(self, *args, **kwargs):
        """
        Constructor with some extra params:

        * verbose: be verbose about what we do. Defaults to True.

        For other params see: zipfile.ZipFile
        """
        self.verbose = kwargs.pop('verbose', True)

        # zipfile.ZipFile is an old-style class, cannot use super() here:
        zipfile.ZipFile.__init__(self, *args, **kwargs)

Python 2 is a little persnickety and funny about mixing *args, **kwargs and additional named keyword arguments; your best bet is to not add additional explicit keyword arguments and just take them from kwargs instead.

The dict.pop() method removes the key from the dictionary, if present, returning the associated value, or the default we specified if missing. This means that we do not pass verbose on to the super class. Use kwargs.get('verbose', True) if you just want to check if the paramater has been set without removing it.

like image 77
Martijn Pieters Avatar answered Sep 17 '22 18:09

Martijn Pieters