Re: [Tutor] (*args, **kwargs)

2006-08-05 Thread John Fouhy
On 05/08/06, Matt Williams <[EMAIL PROTECTED]> 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.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] (*args, **kwargs)

2006-08-04 Thread Etienne Robillard

--- Matt Williams <[EMAIL PROTECTED]>
wrote:

> Dear All,
> 
> I have learnt to do bits of python, but one of the
> things I cannot get 
> my head around is the *args, **kwargs syntax.
> I have tried reading stuff on the web, and I have a
> copy of the python 
> cookbook (which uses it as a recipe early on) but I
> still don't 
> understand it.
> 
> Please could someone explain _very_ slowly?

Here's how I've learned it so far:

First, there's a convention for 'passing lists as
arguments', which is simply to use 'kw' (I prefer that
one) or 'kwargs' with a '*' in front of them.

But first you need to initialize your data structure
properly, thus:

kw = {} # a empty dictionnary

Then you may want to add stuff inside that kw object:

kw['foo'] = "bar"

Now consider the following data structure:
class Foo:
  def __init__(self, **kw):
  # do something with kw objects here.
  pass

Then here's how to pass the whole kw object as a
argument list:
Foo(**kw) 

HTH,

Etienne

> Apologies for the gross stupidity,

P.S - There's no such thing here, sorry. :-)
 
> Matt
> 
> 
> -- 
> http://acl.icnet.uk/~mw
> http://adhominem.blogsome.com/
> +44 (0)7834 899570


--
Etienne Robillard <[EMAIL PROTECTED]>
JID: incidah AT njs.netlab.cz
YMS/MSN: granted14 AT yahoo.com
TEL: +1  514.962.7703
URL: http://www.assembla.com/wiki/show/stn-portfolio/

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] (*args, **kwargs)

2006-08-04 Thread Matt Williams
Dear Etienne & Carlos,

Thanks so much for that - much clearer!

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.

Obviously one way would be:

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 ?

Thanks,

Matt
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] (*args, **kwargs)

2006-08-04 Thread Jordan Greenberg
Matt Williams wrote:
> Dear All,
> 
> I have learnt to do bits of python, but one of the things I cannot get 
> my head around is the *args, **kwargs syntax.
> 
> I have tried reading stuff on the web, and I have a copy of the python 
> cookbook (which uses it as a recipe early on) but I still don't 
> understand it.
> 
> Please could someone explain _very_ slowly?
> 
> Apologies for the gross stupidity,
> 
> Matt

Basically, *args and **kwargs allows you to collect arguments.
Normally, you'd do something like:
*args collects any arguments (other then the positional ones) into a
list, and **kwargs collects arguments into a dictionary.
In [6]: def foo(a, b, c):
   ...: print a, b, c
   ...:

In [7]: foo(1, 2, 3)
1 2 3

but, say you wanted to make it so it could accept any number of
arguments, you could use *args like so:
In [4]: def foo(*args):
   ...: print args
   ...: for each in args:
   ...: print each
   ...:

In [5]: foo(1, 2, 3, 4)
(1, 2, 3, 4)
1
2
3
4

Notice how all the parameters i passed to foo are collected in the list
args.

**kwargs collects arguments of the form key=value into a dictionary,
like so:

In [15]: def foo(**kwargs):
   :print kwargs
   :

In [16]: foo(name="Jordan", email="[EMAIL PROTECTED]")
{'name': 'Jordan', 'email': '[EMAIL PROTECTED]'}

Your functions can then use the list/dictionary as normal.
You can also use these in conjunction with normal positional parameters:

In [27]: def foo(a, b, c, *args, **kwargs):
   :print "Positional arguments:"
   :print a, b, c
   :print "Non-positional argument list:"
   :print args
   :for each in args:
   :print each
   :print "Keyword argument list:"
   :print kwargs
   :for key in kwargs.keys():
   :print "Key: ", key
   :print "Data: ", kwargs[key]
   :

In [28]: foo(1, "monkey", 7.5, 10, 11, 12, name="jordan",
email="[EMAIL PROTECTED]")
Positional arguments:
1 monkey 7.5
Non-positional argument list:
(10, 11, 12)
10
11
12
Keyword argument list:
{'name': 'jordan', 'email': '[EMAIL PROTECTED]'}
Key:  name
Data:  jordan
Key:  email
Data:  [EMAIL PROTECTED]

So, to summarize, *args and **kwargs are basically there so you can
build your functions so that they can accept a variable number of arguments.

We had a thread about this not terribly long ago too, and Kent Johnson
had a great explanation (as per usual) so I expect he'll be along
shortly with either a link to that thread or a better explanation then
mine!

Anyway, I hope this helps!
-Jordan Greenberg

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] *args, **kwargs

2005-01-01 Thread Alan Gauld
> class SomethingLikeThis:
> def __init__(self, **kwargs):
> self.kwargs = kwargs
>
> def show(self):
> for k in self.kwargs.keys():
> v = selfkwargs.get(k)

is this a typo in the mail or a real error?
  v = self.kwargs.get(k)

> print v
>
> I'm probably misunderstanding the purpose of *args and **kwargs
totally.

Don't think so, here's my session:

>>> class C:
...   def __init__(s,**kw):
... s.kw = kw
...   def show(s):
... for k in s.kw.keys():
...   print s.kw[k]
...
>>> c = C(a=42, b=54)
>>> c.show()
42
54
>>>

HTH,

Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] *args, **kwargs

2005-01-01 Thread Kent Johnson
You seem to be on the right track
Luis N wrote:
I'm wondering how I can turn a variable number of keyword arguments
passed to a class into variables for use in said class:
#This so doesn't work
It is helpful if you tell us what you tried and how it failed...
class SomethingLikeThis:
def __init__(self, **kwargs):
self.kwargs = kwargs
def show(self):
for k in self.kwargs.keys():
v = selfkwargs.get(k)
This line does have an error; it is missing a '.':
  v = self.kwargs.get(k)
print v
This works for me:
class SomethingLikeThis:
def __init__(self, **kwargs):
self.kwargs = kwargs
def show(self):
for k, v in self.kwargs.items():
print k, '=', v
s = SomethingLikeThis(a='abc', num=1, phone='888-555-1212')
s.show()
If that doesn't do what you want then give us more details.
Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor