[Tutor] (*args, **kwargs)

John Fouhy john at fouhy.net
Sun Aug 6 01:20:29 CEST 2006


On 05/08/06, Matt Williams <matthew.williams at cancer.org.uk> wrote:
> I guess the next question is _how_ do you use it intelligently? I'm
> interested because I'm trying to put stuff into a db using sqlobject.

One common place to use it is when you are dealing with inheritance.

For example, suppose I'm writing a Tkinter program, and I want to make
my own GUI component.  I might write:

class MyCustomFrame(Tkinter.Frame):
    def __init__(self, parent, foo, bar, baz=None, **kw):
        Tkinter.Frame.__init__(self, parent, **kw)
        # do something with foo, bar, baz; etc.

The reason for doing this is that Tkinter objects support all kinds of
keyword arguments, and this lets me support them in my custom code
without having to explicitely list them all.

Of course, I could also set/override some of the Tkinter keyword
arguments.  eg, I could make a frame with a pink background like this:

class PinkFrame(Tkinter.Frame):
    def __init__(self, parent, **kw):
        kw['background'] = 'pink'         # line 2
        Tkinter.Frame.__init__(self, parent, **kw)

(note that I can't skip line 2, and replace line 3 with
"Tkinter.Frame.__init__(self, parent, background='pink', **kw)"
because if kw already contains a value for background, python will get
confused and throw an exception..)

> class MyClass:
>
>      def __init__(self,**kw)
>          self.property1 = self.kw['property1']
>         self.property2 = self.kw['property2']
>         etc....
>
> Does anyone know of an example of this ?

I'm not sure there's much value in using **kw if you know exactly what
keyword arguments you're expecting.  Although you can be a bit fancy,
eg:

    def __init__(self, **kw):
        for key in **kw:
            setattr(self, key, kw[key])

But you run the risk of writing obscure code that's hard to follow..

If you were implementing the range() function, you would use *args.
Perhaps something like this:

def range(*args):
    if len(args) == 1:
        return _range(0, args[0], 1)
    elif len(args) == 2:
        return _range(args[0], args[1], 1)
    else:
        return _range(args[0], args[1], args[2])    # could replace
this with: return _range(*args)

def _range(start, stop, step):
    # etc

HTH!

-- 
John.


More information about the Tutor mailing list