[Django]-Adding a **kwarg to a class

11đź‘Ť

âś…

That’s because you’re unpacking kwargs to the super constructor.
Try to put this before calling super:

if kwargs.has_key('bases_queryset'):
    bases_queryset = kwargs['bases_queryset']
    del kwargs['bases_queryset']

but it’s not an ideal solution…

👤Keeper

11đź‘Ť

As @Keeper indicates, you must not pass your “new” keyword arguments to the superclass. Best may be to do, before you call super’s __init__:

bqs = kwargs.pop('bases_queryset', None)

and after that __init__ call, check if bqs is not None: instead of using has_key (and use bqs instead of kwargs['bases_queryset'], of course).

An interesting alternative approach is to make a “selective call” higher-order function. It’s a bit of a mess if you have both positional and named arguments (that’s always a bit messy to metaprogram around;-), so for simplicity of exposition assume the function you want to selectively call only has “normal” named arguments (i.e. no **k either). Now:

import inspect

def selective_call(func, **kwargs):
    names, _, _, _ = inspect.getargspec(func)
    usable_kwargs = dict((k,kwargs[k]) for k in names if k in kwargs)
    return func(**usable_kwargs)

with this approach, in your __init__, instead of calling super’s __init__ directly, you’d call
selective_call(super_init, **kwargs) and let this higher-order function do the needed “pruning”. (Of course, you will need to make it messier to handle both positional and named args, ah well…!-)

👤Alex Martelli

Leave a comment