function scope

Stephen Hansen apt.shansen at gmail.com
Mon Feb 2 19:15:45 EST 2009


On Mon, Feb 2, 2009 at 3:40 PM, Baris Demir <demirbaris at gmail.com> wrote:

> Hi everybody,
>
> I am quite new to python and using it for my thesis.  Luckily I found out
> some kind of behavior surprising to me and so unwanted in my code. I could
> not find any explanation, so solution for the code.
> It is simply like this:
>
> /*li = another_module.global_variable
> f=simpleCut(li)
>
> def simpleCut(d=dict()):
>      temp=d
>      for i in temp.keys():
>          if    (temp[i] == .......) :
>             temp[i]=new_value
> return temp
> */
> here /*simpleCut(d=dict())*/ is a function that changes the value of the
> key in the d if it satisfies conditions and returns the new dictionary.
> what i do not understand is, when i checked the original dictionary /*li,*/
> i also found out that, the value of that key(operated in the if statement)
> had also been changed. so, simply, the simpleCut function also changes the
> variables of its own argument, even there is a 'temp' variable. That is a
> scandal for my code:)


In Python, assignment statements simply bind an existing object to a name:
and when you call a function and pass that name in you're not passing the
name but the object itself-- which will now be bound to a new name.

So, if you have:

  li = {"hello": 5}

A dictionary is created, and is bound to the name "li".

If you then call:

   f=simpleCut(li)

The dictionary, previously created, will be bound to a new name within
simpleCut, that of "d".

Within simpleCut, you do:
    temp = d

That's simply binding the same dictionary to a new name. Its also the same
dictionary which is known as "li" somewhere else.

You then later do:
    return temp

That's returning the same dictionary-- as its returning from the function
the object currently bound to the name 'temp'.

That dictionary will end up being assigned to "f" from earlier.

In all of this you have one single dictionary, known by many names. You have
to take care when passing around mutable objects for this reason (and
there's another gotcha you're very near to by assigning a default value to a
mutable object: that default dict() will be the exact same default dict
every time you call the simpleCut() function with no arguments, instead of
it being a new dictionary everytime).

If you want to duplicate a dictionary, you import the copy module and call
copy.copy(d) (or copy.deepcopy(d) depending on the contents). You can also
pass the old dict to the dict() object to get a copy. I -believe- that's a
shallow copy. E.g, return dict(temp) will make a shallow copy.

--S
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090202/a19f306b/attachment-0001.html>


More information about the Python-list mailing list