Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
**kwargs question
#1
Hi,

I have been searching books and the internet to find a useful example for **kwargs in a def() function.
All i find is that you give a series of dict values as parameters (**kwargs) and then they print them out.
I fail to see any added value for that. (could be my ignorance)

Question: it would be better if i could subscript the **kwargs,
like i can with the *args (arg[0] ...
Or somehow find a key and put its value in a particular place of the function.
I can't find how to do that other than what was mentioned above:
def xxx():
  for x in kwargs:
    print(x)
thx,
Dpaul
Reply
#2
def some_func(*args, **kwargs):
    print(f'Positional arguments: {args}')
    print(f'Keyword arguments: {kwargs}')
    print('--------------\n')


pos = {'foo', 'bar'}
keyw = {'spam':1, 'eggs':2}

some_func('foo', spam=1)
some_func('foo', 'bar', spam=1, eggs=2)
some_func(*pos)
some_func(**keyw)
some_func('foo', **keyw)
some_func(*pos, **keyw)
Output:
Positional arguments: ('foo',) Keyword arguments: {'spam': 1} -------------- Positional arguments: ('foo', 'bar') Keyword arguments: {'spam': 1, 'eggs': 2} -------------- Positional arguments: ('foo', 'bar') Keyword arguments: {} -------------- Positional arguments: () Keyword arguments: {'spam': 1, 'eggs': 2} -------------- Positional arguments: ('foo',) Keyword arguments: {'spam': 1, 'eggs': 2} -------------- Positional arguments: ('foo', 'bar') Keyword arguments: {'spam': 1, 'eggs': 2} --------------
Note, args and kwargs are just names used by convention, they can be different.

kwargs is just a dict, so you can work with it like with any other dict. In your example you iterate over keys.

Of course, you can take only positional, only keyword, or force certain arguments to be keyword-only
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
Dear Buran,

Thanks for the reply.
But i have seen dozens of these examples.
I would like to know one of two things:
a) What is the added value of these? You type some stuff (**kwargs) and then you get them back ?? Much ado about nothing at first sight.
b) Or: i type these **kwarg arguments, and now i can find the value of the key i need in the function, but alas, i can't work it out...

I will give an example:
a def circonference(): that calculates the circonference of any number of shapes:
call circonference('triangle', 5, 11, 4, ...
call circonference('square', 17, (only one needed)

for the **kwargs i could add that ..., triangle='blue',square='green'...)
And now in the function i want to make sure that the right color is added to the right shape, no list printing.

Dpaul
Reply
#4
They're just parameters to the function. You can use them anyway you like.
Reply
#5
(Mar-29-2020, 08:43 AM)DPaul Wrote: a) What is the added value of these? You type some stuff (**kwargs) and then you get them back ?? Much ado about nothing at first sight.
The benefit is you can get arbitrary number of positional or keyword arguments.
It is more often used in OOP, when you may need to pass arbitrary arguments. (e.g. for the purpose of instantiating parent class, etc.)

(Mar-29-2020, 08:43 AM)DPaul Wrote: b) Or: i type these **kwarg arguments, and now i can find the value of the key i need in the function, but alas, i can't work it out...

I will give an example:
a def circonference(): that calculates the circonference of any number of shapes:
call circonference('triangle', 5, 11, 4, ...
call circonference('square', 17, (only one needed)

I am not sure I understand your question and example

(Mar-29-2020, 08:43 AM)DPaul Wrote: for the **kwargs i could add that ..., triangle='blue',square='green'...)
Actually this is poor design. I won't go as far as providing example as it is hypothetical case, but.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
Ok, i do not seem to get my point across.

Take Buran's example if that is better: print the "eggs" only.Not the spam.
If that is possible, i will understand.

Dpaul
Reply
#7
Here is an example to calculate circumference of a shape
import math
def circumference(**kwargs):
    try:
        return 2 * math.pi * kwargs['radius']
    except KeyError:
        try:
            return sum(kwargs['sides'])
        except KeyError:
            pass
    raise TypeError(f'Unexpected keyword argument(s): {kwargs}')


print(f'{circumference(radius=2):.3f}')
print(circumference(sides=[3, 4, 5]))
print(circumference(diameter=4))
Output:
12.566 12 Traceback (most recent call last): File "/home/boyan/sandbox2/foo.py", line 15, in <module> print(circumference(diameter=4)) File "/home/boyan/sandbox2/foo.py", line 10, in circumference raise TypeError(f'Unexpected keyword argument(s): {kwargs}') TypeError: Unexpected keyword argument(s): {'diameter': 4}
Note that this is somewhat artificial use case, but anyway it provides an example
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
(Mar-29-2020, 08:02 AM)buran Wrote: def some_func(*args, **kwargs):
I liked the example, it was very clear. But as DPaul said, why those asterisks? It doesn't make very clear what is going on. I think he would like to see something like:
def some_func(args=tuple(), kwargs=dict()):
This makes clear what the arguments should be. And we prefer clear programs, don't we?
But then I tried to make it work. It appeared the calls to the function had to be altered:
some_func(('foo',), {'spam':1})   #was: some_func('foo', spam=1)
some_func(('foo', 'bar'),         #was: some_func('foo', 'bar', spam=1, eggs=2)
          {'spam':1, 'eggs':2})
some_func(pos)                    #was: some_func(*pos)
some_func((), keyw)               #was: some_func(**keyw)
some_func(('foo',), keyw)         #was: some_func('foo', **keyw)
some_func(pos, keyw)              #was: some_func(*pos, **keyw)
Then I saw it didn't get much clearer after all. So the asterisks serve a purpose.
Reply
#9
I think you too miss the point. It's not about being more or less clear. Or only partially - with asterisks it's more clear :-).
Without asterisks you have 2 keyword arguments. That you make default values empty tuple and empty dict does not change the fact that you can pass any type, e.g. some_func(1, 2). In which case args=1 and kwargs=2.
With asterisks you can have arbitatry number of positional and/and keyword arguments and then they are combined in the respective tuple or dict
the asterisks in the function signature is to do the opposite of iterable unpacking.
foo= {'spam':1, 'eggs':2}
print('some string {spam} {eggs}'.format(**foo)) # here you unpack dict foo into multiple arguments for the .format method
Output:
some string 1 2
Also you can see something similar in extended iterable unpacking
foo = [1, 2, 3, 4]
bar, *spam, eggs = foo # here spam will combine all middle values
print(bar)
print(spam)
print(eggs)
Output:
1 [2, 3] 4
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#10
(Mar-29-2020, 09:41 AM)buran Wrote: Here is an example to calculate circumference of a shape
def circumference(**kwargs):
        return 2 * math.pi * kwargs['radius'] 

Dear Buran,

This is exactly what i thought should be possible. Thanks.
I tried many variations, somehow i missed the simplest. Blush
The question remains, why all other **kwarg examples show little "added value".
This one does. It is powerful.

Thanks
Paul
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How do I instantiate a class with **kwargs? palladium 6 7,359 Feb-16-2023, 06:10 PM
Last Post: deanhystad
  kwargs question Jeff_t 8 2,962 Feb-16-2022, 04:33 PM
Last Post: Jeff_t
  Misunderstanding kwargs? Donovan 2 2,275 Aug-04-2020, 08:09 PM
Last Post: Donovan
  Unpacking dictionary from .xlsx as Kwargs etjkai 5 2,855 Dec-27-2019, 05:31 PM
Last Post: etjkai
  opts vs kwargs Skaperen 4 2,460 Nov-30-2019, 04:57 AM
Last Post: Skaperen
  create dictionary from **kwargs that include tuple bluefrog 2 4,877 Oct-26-2016, 10:24 PM
Last Post: Larz60+
  How do you use *args and **kwargs? Gengar 3 19,669 Sep-20-2016, 04:22 PM
Last Post: Ofnuts

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020