[Tutor] passing form data into a class

John Fouhy john at fouhy.net
Wed Aug 1 04:40:35 CEST 2007


On 01/08/07, tpc247 at gmail.com <tpc247 at gmail.com> wrote:
> John, I spent the last two hours trying to understand what you wrote, and I
> feel I'm missing something:
>
>  >>> a_dict = {'one':1, 'two':2, 'three':3}
>  >>> class A(object):
>      def __init__(self, **kwargs):
>          for var in kwargs:
>              setattr(self, var, locals()[var])

Well, that's one risk of using something like locals() -- it can be
fragile with respect to transformations that wouldn't otherwise make
much difference.

Try this:

 a_dict = {'one':11, 'two':22}
class A(object):
  def __init__(self, one=1, two=2):
    print locals()
A(**a_dict)

And this:

class B(object):
  def __init__(self, **kwargs):
    print locals()
B(**a_dict)

Do you see the difference?  With B, you could write:

class B(object):
  def __init__(self, **kwargs):
    for var in kwargs:
      setattr(self, var, kwargs[var])

Although, as Kent points out, you can more simply write
'self.__dict__.update(kwargs)'.

> >>> class A(object):
>      def __init__(self, **kwargs):
>          for var in locals():
>              setattr(self, var, locals()[var])
>  >>> a_inst = A(**a_dict)
>  RuntimeError: dictionary changed size during iteration

And that illustrates another risk of using locals() (and a risk of not
testing my code before posting it).  What's happening is that python
is inserting 'var' into locals() immediately after starting the loop,
which is breaking iteration.  You could fix this by saying:

  for var in locals().keys():
    # etc

But a few other people have weighed in with suggestions that should be
less fragile, so you may want to go with their ideas instead.

-- 
John.


More information about the Tutor mailing list