Friday, 16 November 2018

python - Why can a function modify some arguments as perceived by the caller, but not others?



I'm trying to understand Python's approach to variable scope. In this example, why is f() able to alter the value of x, as perceived within main(), but not the value of n?



def f(n, x):

n = 2
x.append(4)
print('In f():', n, x)

def main():
n = 1
x = [0,1,2,3]
print('Before:', n, x)
f(n, x)
print('After: ', n, x)


main()


Output:



Before: 1 [0, 1, 2, 3]
In f(): 2 [0, 1, 2, 3, 4]
After: 1 [0, 1, 2, 3, 4]


Answer



Some answers contain the word "copy" in a context of a function call. I find it confusing.



Python doesn't copy objects you pass during a function call ever.



Function parameters are names. When you call a function Python binds these parameters to whatever objects you pass (via names in a caller scope).



Objects can be mutable (like lists) or immutable (like integers, strings in Python). Mutable object you can change. You can't change a name, you just can bind it to another object.



Your example is not about scopes or namespaces, it is about naming and binding and mutability of an object in Python.




def f(n, x): # these `n`, `x` have nothing to do with `n` and `x` from main()
n = 2 # put `n` label on `2` balloon
x.append(4) # call `append` method of whatever object `x` is referring to.
print('In f():', n, x)
x = [] # put `x` label on `[]` ballon
# x = [] has no effect on the original list that is passed into the function


Here are nice pictures on the difference between variables in other languages and names in Python.



No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...