function scope

B

Baris Demir

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 == .......) :
temp=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:)

please tell me, if this is not possible and i am missing another thing
in my code, or if this kind of behavior is possible, what is the
philosophy of it, and how can i change it???

cheers

B.D.
 
S

Steven D'Aprano

def simpleCut(d=dict()):
       temp=d
       for i in temp.keys():
           if    (temp == .......) :
              temp=new_value
return temp


You have been bitten by the shared default parameter noobie trap:


No, he has tripped over the assignment-doesn't-make-copies feature.
Ignore the default value, and consider passing in a dict:


def simpleCut(d=dict()):
    temp=d
# ...

That doesn't make a temporary copy of d, it makes a new name that refers
to the same dictionary as d. So if you do this:

li = {'x': 1}
f = simpleCut(li)

then

assert f is li

will pass, and he will be surprised and dismayed to discover that
simpleCut() has side-effects.


Solution: make a copy of the input.


def simpleCut(d=dict()):
temp = d.copy()
for i in temp: # don't need to call keys()
if (temp == ...):
temp = new_value
return temp
 
T

Tim Roberts

Mike Kent said:
def simpleCut(d=dict()):
       temp=d
       for i in temp.keys():
           if    (temp == .......) :
              temp=new_value
return temp


You have been bitten by the shared default parameter noobie trap:
http://www.python.org/doc/faq/general/#why-are-default-values-shared-between-objects


Actually, he hasn't. His problem is more fundamental.

However, this is still a good thing for you to point out now and then.
 
B

Baris Demir

Tim said:
Mike Kent said:
def simpleCut(d=dict()):
temp=d
for i in temp.keys():
if (temp == .......) :
temp=new_value
return temp

You have been bitten by the shared default parameter noobie trap:
http://www.python.org/doc/faq/general/#why-are-default-values-shared-between-objects


Actually, he hasn't. His problem is more fundamental.

However, this is still a good thing for you to point out now and then.


Thanks a lot for the replies guys. They all helped a lot. And, I guess,
I should read a lot more about python, it is not as simple as it seems
at the beginning, or for the beginners:)
cheers
BD
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,084
Latest member
HansGeorgi

Latest Threads

Top