Michael
Michael

Reputation: 13914

Modifying Local Within Function Changes Global Passed to Function in Python

I am trying to understand why the global copy of an object passed to a function is modified by the function. I understand that if I assign an object mylist to a second variable name, it does not make a copy and modifying the second object changes the first because they are one in the same. For example:

mylist = []
s = mylist
s.append(2)
print(mylist)
[2]

However, I did not think this occurred within a function unless made explicit with global varname. As this answer puts it, "If you want to simply access a global variable you just use its name. However to change its value you need to use the global keyword." This is how the function mult below behaves (though I am not modifying x but assigning a new value to it). However, when I pass a global variable to either app or noreturn, in both instances the global variable is modified by the function without a declaration that I want to modify the global variable with a global keyword.

import pandas as pd

def mult(x):
    x = x * x
    return x

def app(mylist):
    mylist.append(4)
    return mylist


def noreturn(df):
    df['indexcol'] = list(df.index)

df = pd.DataFrame({"A": [10,20,30,40,50], "B": [20, 30, 10, 40, 50], "C": [32, 234, 23, 23, 42523]})
print(df)

    A   B      C
0  10  20     32
1  20  30    234
2  30  10     23
3  40  40     23
4  50  50  42523



noreturn(df)
print(df)

    A   B      C  indexcol
0  10  20     32         0
1  20  30    234         1
2  30  10     23         2
3  40  40     23         3
4  50  50  42523         4



x = 3
mylist = []

y = mult(x)
newlist = app(mylist)
print(x, y)
(3, 9)
print(mylist, newlist)
([4], [4])

If I want a function that does not modify global variables do I need to use copy.deepcopy on every variable passed to the function?

Upvotes: 0

Views: 421

Answers (1)

Greg Hewgill
Greg Hewgill

Reputation: 993451

Your quote says:

If you want to simply access a global variable you just use its name. However to change its value you need to use the global keyword.

I would modify that to:

If you want to simply access the object a global variable refers to, you just use its name. However to change what object it refers to, you need to use the global keyword.

Accessing a global object can include changing things about the object (such as appending a new object to an existing global list). However, if your function tried to do:

def app(mylist):
    mylist = mylist + [4]
    return mylist

which attempts to change the global mylist reference (by creating a new object and assigning the result to mylist), then you would need to use the global keyword.

Upvotes: 1

Related Questions