Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the scope of a variable in a function? Python [duplicate]

This may seem like a really stupid question but I am confused regarding the scope rules in Python. In the following example I send two variables (x,y) with values to a function which is supposed to change their values. When I print the results the variables had not changed.

def func1(x,y):
    x=200
    y=300

x=2
y=3

func1(x,y)

print x,y #prints 2,3

Now if this were C++ I would send them by reference (&) to that function and therefore be able to change their values. So what's the equivilant in Python? and more important, what actually happens when you send objects to function? does Python make new references to these objects?

like image 294
Reboot_87 Avatar asked Jan 16 '14 17:01

Reboot_87


1 Answers

Think of them as being part of the function. When the function ends, all its variables die too.

x=2
y=3

def func(x,y):
    x=200
    y=300

func(x,y) #inside this function, x=200 and y=300
#but by this line the function is over and those new values are discarded
print(x,y) #so this is looking at the outer scope again

If you want a function to modify a value in exactly the way you have written it, you could use a global but this is VERY bad practice.

def func(x,y):
    global x #these tell the function to look at the outer scope 
    global y #and use those references to x and y, not the inner scope
    x=200
    y=300

func(x,y)
print(x,y) #prints 200 300

The problem with this is that it makes debugging a nightmare in the best case, and utterly incomprehensibly impossible in the worst case. Things like these are commonly known as "side effects" in functions -- setting a value you don't need set and doing so without explicitly returning it is kind of a Bad Thing. Generally the only functions you should write that modify items in-place are object methods (things like [].append() modify the list because it's silly to return a new list instead!)

The RIGHT way to do something like this would be to use a return value. Try something like

def func(x,y):
    x = x+200 #this can be written x += 200
    y = y+300 #as above: y += 300
    return (x,y) #returns a tuple (x,y)

x = 2
y = 3
func(x,y) # returns (202, 303)
print(x,y) #prints 2 3

Why didn't that work? Well because you never told the program to DO anything with that tuple (202, 303), just to calculate it. Let's assign it now

#func as defined above

x=2 ; y=3
x,y = func(x,y) #this unpacks the tuple (202,303) into two values and x and y
print(x,y) #prints 202 303
like image 100
Adam Smith Avatar answered Nov 03 '22 00:11

Adam Smith