Python Forum
Passing an argument by reference
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Passing an argument by reference
#1
Can you pass an argument by reference with data structures other than lists?

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)
This will alter a list. Can you pass an argument by reference to alter other data structures, like variables? I tried to alter a variable this way, and it didn't work for me.
Reply
#2
The issue is whether the data type is mutable or immutable. Lists, sets, and dictionaries are mutable and are passed by reference. Tuples, strings, frozensets, ints, and floats are immutable and are passed by value.

Note that user created classes are considered to be immutable, and thus passed by reference. So you could make a class that is a wrapper for an immutable type to pass it sort of by reference. Of course, it would probably be easier to pass it as a one item list.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
(Aug-10-2019, 03:49 PM)ichabod801 Wrote: The issue is whether the data type is mutable or immutable. Lists, sets, and dictionaries are mutable and are passed by reference. Tuples, strings, frozensets, ints, and floats are immutable and are passed by value.

Note that user created classes are considered to be immutable, and thus passed by reference. So you could make a class that is a wrapper for an immutable type to pass it sort of by reference. Of course, it would probably be easier to pass it as a one item list.

If a variable contains an immutable data type, does that make the variable immutable (for the purposes of passing an argument by reference)?
Reply
#4
Yes. In fact reference/value comes into play with variables themselves. Take this:

x = 5
y = x
a = [5]
b = a

y += 8
b.append(8)
At the end of this, x will still be 5. Since ints are immutable, the assignment was done by value. The value of a, however, will be [5, 8]. Since a list is mutable, it was assigned by reference.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
(Aug-10-2019, 03:49 PM)ichabod801 Wrote: The issue is whether the data type is mutable or immutable. Lists, sets, and dictionaries are mutable and are passed by reference. Tuples, strings, frozensets, ints, and floats are immutable and are passed by value. Note that user created classes are considered to be immutable, and thus passed by reference. So you could make a class that is a wrapper for an immutable type to pass it sort of by reference. Of course, it would probably be easier to pass it as a one item list.

Can you please give some hint on creating a wrapper class which will work on immutable class
Reply
#6
Exsul Wrote:Can you pass an argument by reference to alter other data structures, like variables? I tried to alter a variable this way, and it didn't work for me.
Python never calls 'by value' in the sense that it doesn't make a copy of any function's argument. For each argument, it copies only the address of a python object which is a 'value' in the python sense. So this discussion about call by value and call by reference is ambiguous. Python passes only addresses of structures used as values.

What python cannot do (and this is the way I understand your question) is pass a reference to a variable as you would do in C when you write foo(&x) for example. The only way to reference a variable in python is to do it symbolically, that is to say if the variable is named 'x', use the word 'x'. So a python function cannot easily change the value of a variable in the calling environment. The usual workaround is to change the value of instances attributes, for example

def func(a):
    a.foo = 5 # changes the value of attribute foo of object a
Reply
#7
(Aug-10-2019, 03:49 PM)ichabod801 Wrote: The issue is whether the data type is mutable or immutable. Lists, sets, and dictionaries are mutable and are passed by reference. Tuples, strings, frozensets, ints, and floats are immutable and are passed by value.

Not complete right. All names are also references also to immutable objects. You still have the reference to the in memory living object, but you can't change the content (str, bytes, tuple, int, float, complex, frozenset).

If you want to affect the outer scope of a function, you can mutate objects inside the function. The other possibility is, to use globals. Don't use them.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
>>> x = 0
>>> def inc(number):
...     print(id(x))
...     print(id(number))
...     number += 1
...     print(id(x))
...     print(id(number))
...     return number
...
>>> inc(x)
140718032253152
140718032253152
140718032253152
140718032253184
1
>>>
The local "variable" number is a reference to x. They have the same memory address. Then number is increased by 1. Because the integers are immutable type this operation can't change the value of x and a new variable with value 1 with a new address is created and now number is pointing to it. This is how memory in Python works. All names are references to an object and then it comes if they are mutable or not.
As already stated the names keep the memory address to a variable. So these addresses are passed as an argument.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#9
(Aug-20-2019, 06:08 AM)Gribouillis Wrote:
Exsul Wrote:Can you pass an argument by reference to alter other data structures, like variables? I tried to alter a variable this way, and it didn't work for me.
Python never calls 'by value' in the sense that it doesn't make a copy of any function's argument. For each argument, it copies only the address of a python object which is a 'value' in the python sense. So this discussion about call by value and call by reference is ambiguous. Python passes only addresses of structures used as values. What python cannot do (and this is the way I understand your question) is pass a reference to a variable as you would do in C when you write foo(&x) for example. The only way to reference a variable in python is to do it symbolically, that is to say if the variable is named 'x', use the word 'x'. So a python function cannot easily change the value of a variable in the calling environment. The usual workaround is to change the value of instances attributes, for example
 def func(a): a.foo = 5 # changes the value of attribute foo of object a 

I tried to change the value of the instance attribute in this way

 def f(a):
...     a.foo =5
...     print(foo)
...
>>> foo=6
>>> f(1)
If I run like above, I'm hitting
Error:
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in f AttributeError: 'int' object has no attribute 'foo'
Reply
#10
Malt Wrote:I tried to change the value of the instance attribute in this way
You can't change the value of global variables this way, and you can't add attributes to builtin types which are not defined in pure python. You can use it to add attributes of user defined types, for example:
class Spam:
    pass

def func(a):
    a.foo = 5

s = Spam()
func(s)
print(s.foo) # prints 5
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Passing Argument Errors cosmarchy 6 2,437 Sep-29-2021, 06:09 AM
Last Post: snippsat
  Passing argument from top-level function to embedded function JaneTan 2 2,257 Oct-15-2020, 03:50 PM
Last Post: deanhystad
  Pass by object reference when does it behave like pass by value or reference? mczarnek 2 2,557 Sep-07-2020, 08:02 AM
Last Post: perfringo
  Mathplotlib - passing reference to axs to function qmfoam 5 2,962 Aug-17-2020, 09:02 PM
Last Post: qmfoam
  SyntaxError: positional argument follows keyword argument syd_jat 3 5,830 Mar-03-2020, 08:34 AM
Last Post: buran
  passing an argument to avoid a global Skaperen 9 3,867 Jul-12-2019, 11:07 PM
Last Post: Skaperen
  Passing by reference or value CanadaGuy 4 2,979 Nov-12-2018, 08:44 PM
Last Post: CanadaGuy
  Passing a list by reference virgik89 6 4,518 Jul-01-2018, 04:26 PM
Last Post: virgik89

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020