1
class CashRegister:
    def __init__(self, user, **kwargs):
        self.user = user
        self.items = kwargs

myRegister = CashRegister('name')

print(type(myRegister.items))

The above code tells me that self.items argument (output: <class 'dict'>) is a dictionary. So it exists. But, when I do this.

myRegister = CashRegister('name', {'a': 1, 'b': 2})

I get the following error.

myRegister = CashRegister('name', {'a': 1, 'b': 2}) TypeError: __init__() takes 2 positional arguments but 3 were given

What am I doing wrong?

tym
  • 63
  • 8
  • `**kwargs` in a function definition signature *makes your function take an arbitrary number of keyword arguments. These will be grouped into a `dict` inside your unfction, `kwargs`. When you call your function like this: `CashRegister('name', {'a': 1, 'b': 2})` you haven't provided *any* keyword arguments, you provided 2 positional arguments, but you've only defined your function to take one, `name`. Hence the error – juanpa.arrivillaga Nov 14 '20 at 08:37

2 Answers2

2

You need to "double-splat" on both ends. Call your function like so:

R2 = CashRegister('name', **{'fish':19.99, 'frisbee':14.98})
print(R2.items)

Output:

{'fish': 19.99, 'frisbee': 14.98}
Prune
  • 76,765
  • 14
  • 60
  • 81
1

If you want to pass a dict into the function, you don't need the ** — that spreads them out into individual keyword arguments. Just make it a single argument which will accept the dictionary:

class CashRegister:
    def __init__(self, user, items):
        self.user = user
        self.items = items

c = CashRegister('name', {'a': 1, 'b': 2})
print(c.items)
# {'a': 1, 'b': 2}
Mark
  • 90,562
  • 7
  • 108
  • 148
  • 1
    Mark, I am beginner. Did not know I could do this. Thank you so much! – tym Nov 14 '20 at 06:54
  • @jpsamudrala the whole `*args` `**kwargs` convention was a little difficult at first for me. Take a little time and use to get used to it. – Mark Nov 14 '20 at 06:55