Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Without pointers, can I pass references as arguments in Python? [duplicate]

Since Python doesn't have pointers, I am wondering how I can pass a reference to an object through to a function instead of copying the entire object. This is a very contrived example, but say I am writing a function like this:

def some_function(x):
    c = x/2 + 47
    return c

y = 4
z = 12

print some_function(y)
print some_function(z)

From my understanding, when I call some_function(y), Python allocates new space to store the argument value, then erases this data once the function has returned c and it's no longer needed. Since I am not actually altering the argument within some_function, how can I simply reference y from within the function instead of copying y when I pass it through? In this case it doesn't matter much, but if y was very large (say a giant matrix), copying it could eat up some significant time and space.

like image 792
hannah Avatar asked Mar 21 '14 12:03

hannah


2 Answers

Your understanding is, unfortunately, completely wrong. Python does not copy the value, nor does it allocate space for a new one. It passes a value which is itself a reference to the object. If you modify that object (rather than rebinding its name), then the original will be modified.

Edit

I wish you would stop worrying about memory allocation: Python is not C++, almost all of the time you don't need to think about memory.

It's easier to demonstrate rebinding via the use of something like a list:

def my_func(foo):
    foo.append(3)  # now the source list also has the number 3
    foo = [3]      # we've re-bound 'foo' to something else, severing the relationship
    foo.append(4)  # the source list is unaffected
    return foo


original = [1, 2]
new = my_func(original)

print original     # [1, 2, 3]
print new          # [3, 4]

It might help if you think in terms of names rather than variables: inside the function, the name "foo" starts off being a reference to the original list, but then we change that name to point to a new, different list.

like image 70
Daniel Roseman Avatar answered Oct 21 '22 04:10

Daniel Roseman


Python parameters are always "references".

The way parameters in Python works and the way they are explained on the docs can be confusing and misleading to newcomers to the languages, specially if you have a background on other languages which allows you to choose between "pass by value" and "pass by reference".

In Python terms, a "reference" is just a pointer with some more metadata to help the garbage collector do its job. And every variable and every parameter are always "references".

So, internally, Python pass a "pointer" to each parameter. You can easily see this in this example:

>>> def f(L):
...     L.append(3)
... 
>>> X = []
>>> f(X)
>>> X
[3]

The variable X points to a list, and the parameter L is a copy of the "pointer" of the list, and not a copy of the list itself.

Take care to note that this is not the same as "pass-by-reference" as C++ with the & qualifier, or pascal with the var qualifier.

like image 37
vz0 Avatar answered Oct 21 '22 04:10

vz0