[Tutor] Proper way to use **kwargs?

Rich Lovely roadierich at googlemail.com
Tue Mar 16 00:33:11 CET 2010


On 15 March 2010 12:38, Karjer Jdfjdf <karper12345 at yahoo.com> wrote:

> I want to use **kwargs to check a list of conditions (if true do this, if
> false do nothing) besides required parameters ( in sample a and b).
> Sometimes I want to add a Python object (in example a dictionary and a
> list). Below is my first **kwargs-brew.
>
> ###START
>
> def function_with_kwargs(a, b, **kwargs):
>     options = {
>         'logfile'   : None,
>         'door'      : 'kitchendoor',
>         'roof'      : 'tiles',
>         'mydict'    : None,
>         'mylist'    : None, }
>     options.update(kwargs)
>
>     logfile = options.get('logfile')
>     if logfile == None:
>         print "No logging"
>     else:
>         print "Logging"
>
>     mydict = options.get('mydict')
>     if mydict == None:
>         print "Do nothing with dictionary"
>     else:
>         print "Do something with dictionary"
>
>     mylist = options.get('mylist')
>     if mylist == None:
>         print "Do nothing with list"
>     else:
>         print "Do something with list"
>
>     print "END OF FUNCTION\n"
>
>
> somedict = { 'a': '1', 'b': '2', }
> somelist = ['1', '2']
>
> #DO SOMETHING
> function_with_kwargs(1, 2, logfile='log.txt', door='frontdoor',
> mydict=somedict, mylist=somelist)
>
> #DO NOTHING
> function_with_kwargs(1, 2, door='frontdoor')
>
> ### END
>
> I have 2 questions about this code:
>
> 1. Can I use this in Python 3 ?  I'm not sure if I can use **kwargs in
> Python 3 because it uses the "apply" builtin (if I understand it correctly)
>
> "At this writing, both apply and the special call syntax described in this
> section can be used freely in Python 2.5, but it seems likely that apply
> may go away in Python 3.0. If you wish to future-proof your code, use
> the equivalent special call syntax, not apply."
>
> 2. Are there better ways to achieve what I want to do?
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>
This is not the intended use of kwargs.  **kwargs is intended for situations
where you don't know what the keyword arguments are going to be when you
write the function.  The dict() function is a good example.  It is quite
possible to write dict(foo=1, bar=2).  In your example, however, you know
exactly what the keywords are going to be, so all kwargs does is muddy the
function signature, so when you're using the function, you need to look at
more than just the first line to see what arguments it takes.  A better way,
in my opinion, would be to use optional arguements:

def function_with_kwargs(a,
b, logfile=None, door='kitchendoor', roof='tiles', mydict=None, mylist=None):
   # etc

Its quite easy to see why this is an improvement if you load the function
definition into idle, and then start typing the function name. A tooltip
will pop up, listing all the arguments it can take.

You can still use the function in exactly the same way as with **kwargs, it
just won't hand you a dictionary holding the arguments passed in. It does,
however, eliminate the need for lines like

mydict = options.get('mydict')

You can just jump straight to checking

    if mydict is None:
        #do stuff

Of course, this approach gets impractical if you've got hundreds of named
arguments, but that's probably a pretty good sign that you're doing
something wrong.

-- 
Rich "Roadie Rich" Lovely

Just because you CAN do something, doesn't necessarily mean you SHOULD.
In fact, more often than not, you probably SHOULDN'T.  Especially if I
suggested it.

10 re-discover BASIC
20 ???
30 PRINT "Profit"
40 GOTO 10
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20100315/f643e326/attachment.html>


More information about the Tutor mailing list