How to pass all arguments from __init__ to super class
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.
Nux
I like JavaScript just for fun and rapid creation of code that is usable for me and can be usable for others. I also speak other programming languages ;-). As for me on Stacks - I ask hard questions, but I really appreciate even when someone gives me clues on how to get to the answer :-].
Updated on June 03, 2022Comments
-
Nux about 2 years
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)
-
glglgl about 11 yearsOr
self.verbose = kwargs.pop('verbose', verbosedefaultvalue)
-
Martijn Pieters about 11 years@glglgl: indeed, much beter, I forgot
pop()
takes a default. -
Ber about 11 yearsYou may also want to consider
self.verbose = kwargs.get('verbose', verbosedefaultvalue)
in case you want to look at args that also do the the super class method. -
Martijn Pieters about 11 years@Ber: There, made that more explicit.
-
Nux about 11 yearsThat does seem to work in terms of params, but I'm getting
TypeError: super() argument 1 must be type, not classobj
. And so to my knowledge I cannot inherit fromzipfile.ZipFile
and usesuper
as the original class is an old style class :-(. At least on Python 2.6.6. But thanks I'll use this in some other case. -
Martijn Pieters about 11 years@Nux: Then
zipfile.ZipFile.__init__(self, *args, **kwargs)
will work; same principle applies. -
Nux about 11 yearsThanks! I forgot about passing self and though it just won't work.