Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I thought Python passed everything by reference?

Tags:

python

scope

Take the following code

#module functions.py
def foo(input, new_val):
    input = new_val

#module main.py
input = 5
functions.foo(input, 10)

print input

I thought input would now be 10. Why is this not the case?

like image 981
Ferguzz Avatar asked Nov 18 '11 14:11

Ferguzz


People also ask

Is Python always pass by reference?

Python always uses pass-by-reference values. There isn't any exception. Any variable assignment means copying the reference value.

Are Python arguments passed by reference or value?

All parameters (arguments) in the Python language are passed by reference. It means if you change what a parameter refers to within a function, the change also reflects back in the calling function.

Is Python assignment by reference?

Python utilizes a system, which is known as “Call by Object Reference” or “Call by assignment”. In the event that you pass arguments like whole numbers, strings or tuples to a function, the passing is like call-by-value because you can not change the value of the immutable objects being passed to the function.

Does Python return by value or reference?

In Python, arguments are always passed by value, and return values are always returned by value. However, the value being returned (or passed) is a reference to a potentially shared, potentially mutable object.


3 Answers

Everything is passed by value, but that value is a reference to the original object. If you modify the object, the changes are visible for the caller, but you can't reassign names. Moreover, many objects are immutable (ints, floats, strings, tuples).

like image 186
Sven Marnach Avatar answered Oct 06 '22 01:10

Sven Marnach


Inside foo, you're binding the local name input to a different object (10). In the calling context, the name input still refers to the 5 object.

like image 33
hochl Avatar answered Oct 06 '22 01:10

hochl


Assignment in Python does not modify an object in-place. It rebinds a name so that after input = new_val, the local variable input gets a new value.

If you want to modify the "outside" input, you'll have to wrap it inside a mutable object such as a one-element list:

def foo(input, new_val):
    input[0] = new_val

foo([input])

Python does not do pass-by-reference exactly the way C++ reference passing works. In this case at least, it's more as if every argument is a pointer in C/C++:

// effectively a no-op!
void foo(object *input, object *new_val)
{
    input = new_val;
}
like image 44
Fred Foo Avatar answered Oct 06 '22 01:10

Fred Foo