Got an unexpected keyword argument, genuinely stumped

456 Views Asked by At

I've got the following code. I'll include only the problematic bits:

class C:
    def __init__(self,**kwargs):
        self.kwargs = kwargs

    def fit(...):
        ...
        c = self.learner(**self.kwargs)

I'm attempting to use this with the following class:

class learner:
    def __init__(self, X):
        self.X = X
kwargs={'X': X}
inst = C(kwargs=kwargs)
inst.fit(...)

Which is yielding the error, at the line inst.fit(...). The error is: learner.__init__() got an unexpected keyword argument 'kwargs'. How do I fix my instantiation? It seems as though the dictionary is not being unpacked, despite employing **. Help would be very appreciated.

2

There are 2 best solutions below

0
tobifasc On

By destructuring your kwargs in the constructor of Boost what you are actually storing in self.kwargs is a dictionary that looks like this:

{'kwargs': {'X': x_train, 'y': y_train, 'stride': 12, 's_stride': 17 }

Passing this to the wk_learner constructor using **self.kwargs means python tries to look for a keyword argument called kwargs which doesn't exist, hence the error message.

You can fix the problem by not destructuring in the Boost constructor (and maybe also renaming the parameter to avoid confusion):

def __init__(self, base_learner, base_learner_kwargs):
    self.base_learner = base_learner
    self.base_learner_kwargs = base_learner_kwargs

def fit(self, X: np.ndarray, y: np.ndarray):
    ...
    clf = self.base_learner(**self.base_learner_kwargs)
0
Oskar Hofmann On

The problem is that you explicitly define a keyword argument kwargs in your function call

inst = Boost(base_learner=wk_learner, kwargs=kwargs)

which your wk_learner class does not know how to use.

What I assume you want to do is to just just pass the contents of kwargs via

inst = Boost(base_learner=wk_learner, **kwargs)

Note that args and kwargs are not defined names for a list of arguments and a dictionary of keyword arguments. They are just established default names. You can use any variable name instead.