Skip to content
Fix Code Error

How do I pass a variable by reference?

March 13, 2021 by Code Error
Posted By: Anonymous

The Python documentation seems unclear about whether parameters are passed by reference or value, and the following code produces the unchanged value ‘Original’

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.change(self.variable)
        print(self.variable)

    def change(self, var):
        var = 'Changed'

Is there something I can do to pass the variable by actual reference?

Solution

Arguments are passed by assignment. The rationale behind this is twofold:

  1. the parameter passed in is actually a reference to an object (but the reference is passed by value)
  2. some data types are mutable, but others aren’t

So:

  • If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart’s delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you’re done, the outer reference will still point at the original object.

  • If you pass an immutable object to a method, you still can’t rebind the outer reference, and you can’t even mutate the object.

To make it even more clear, let’s have some examples.

List – a mutable type

Let’s try to modify the list that was passed to a method:

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)

Output:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

Since the parameter passed in is a reference to outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.

Now let’s see what happens when we try to change the reference that was passed in as a parameter:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

Since the the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The the_list was a copy of the outer_list reference, and we had the_list point to a new list, but there was no way to change where outer_list pointed.

String – an immutable type

It’s immutable, so there’s nothing we can do to change the contents of the string

Now, let’s try to change the reference

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

Output:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

Again, since the the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The the_string was a copy of the outer_string reference, and we had the_string point to a new string, but there was no way to change where outer_string pointed.

I hope this clears things up a little.

EDIT: It’s been noted that this doesn’t answer the question that @David originally asked, “Is there something I can do to pass the variable by actual reference?”. Let’s work on that.

How do we get around this?

As @Andrea’s answer shows, you could return the new value. This doesn’t change the way things are passed in, but does let you get the information you want back out:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

If you really wanted to avoid using a return value, you could create a class to hold your value and pass it into the function or use an existing class, like a list:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

Although this seems a little cumbersome.

Answered By: Anonymous

Related Articles

  • Can't install via pip because of egg_info error
  • Getting a problem in django url when I am at url…
  • What's the difference between eval, exec, and compile?
  • Python is not calling fucntions properly
  • correct way to use super (argument passing)
  • How not to get a repeated attribute of an object?
  • Combining pyOSC with pyQT5 / Threading?
  • Usage of __slots__?
  • Why do we use __init__ in Python classes?
  • How does Python's super() work with multiple inheritance?
  • What is The Rule of Three?
  • Azure CLI - az deployment group create -…
  • How to import classes defined in __init__.py
  • Python Variable Declaration
  • Tkinter Custom Rectangle widget
  • What are type hints in Python 3.5?
  • QGraphicsItem don't change pen of parent when chaning child
  • How do I programmatically change the parent of a layout
  • Why does my convolutional model does not learn?
  • How do I include certain conditions in SQL Count
  • Creating a singleton in Python
  • What does this symbol mean in JavaScript?
  • Azure Availability Zone ARM Config
  • Kivy WebView Error: Cannot add to window, it already…
  • coercing to Unicode: need string or buffer, NoneType…
  • How to update Python?
  • How to monitor a filtered version of a metric in…
  • What is an optional value in Swift?
  • Call a method from a method of another class (Nested Class)
  • What does Ruby have that Python doesn't, and vice versa?
  • What is the copy-and-swap idiom?
  • How do I merge two dictionaries in a single…
  • How does the @property decorator work in Python?
  • Multiple context menu in a single qTableView pyqt5
  • Elegant ways to support equivalence ("equality") in…
  • Python extending with - using super() Python 3 vs Python 2
  • Python File Error: unpack requires a buffer of 16 bytes
  • What are the differences between "=" and "
  • Adding animation to QPushbutton enterEvent and exitEvent
  • Python list processing
  • Relative imports for the billionth time
  • Interrupt an earlier timeout event in Simpy
  • Install pip in docker
  • Layout doesn't expand more than initial size it was…
  • Reference - What does this regex mean?
  • Passing variables, creating instances, self, The…
  • Smart way to truncate long strings
  • Trouble understanding behaviour of modified VGG16…
  • How to pass class instance and all it does to…
  • How to simplify sequential logic design by…
  • Why Do I get a Stack Overflow error when using…
  • How to call Base Class's __init__ method from the…
  • Switch between two frames in tkinter
  • How to use QThread() within class of QWidget function?
  • Matplotlib plot's title is missing for unknown…
  • What does "Fatal error: Unexpectedly found nil while…
  • Is there a way to pass optional parameters to a function?
  • Tkinter understanding mainloop
  • Can I access results of "setup_data" from…
  • How to move the player across a one background image?
  • Is it possible to run custom code before Swagger…
  • DQN Pytorch Loss keeps increasing
  • Angular 4 HttpClient Query Parameters
  • python 3.8 tkinter calling new window from method…
  • Best way to bind textfield to a model in ember
  • What are metaclasses in Python?
  • Correctly Parsing JSON in Swift 3
  • Best way to replace multiple characters in a string?
  • Where and why do I have to put the "template" and…
  • My Button Functions Are Not Working in my Python code
  • Python-coded neural network does not learn properly
  • How to invoke the super constructor in Python?
  • jQuery Mobile: document ready vs. page events
  • Ukkonen's suffix tree algorithm in plain English
  • Azure Pipelines compare Key Vault Secrets in Condition
  • Donut piechart in mplcanvas
  • PyQT5: how to automatically align the widget in QGridLayout?
  • How do I bind the enter key to a function in tkinter?
  • What does if __name__ == "__main__": do?
  • function.name returns empty string if the function…
  • Modifying SIR model to include stochasticity
  • How to return a negative fraction when subtracting…
  • Accessing a class' member variables in Python?
  • Proper way to declare custom exceptions in modern Python?
  • The result is not as intended, the output is a bound…
  • Why is "1000000000000000 in range(1000000000000001)"…
  • How would I access variables from one class to another?
  • ImportError: No module named dateutil.parser
  • Simulating a system of resource with…
  • Fast way of finding lines in one file that are not…
  • wxpython do action before closing wx.EVT_CLOSE
  • How to Connect a Django Model with ManyToMany Relationship?
  • Backbone.js Backbone.wrapError function
  • How can I connect a signal to different slots…
  • Python Tkinter Spinboxes return value using for loops
  • Importing a function from a class in another file?
  • Are dictionaries ordered in Python 3.6+?
  • Complex Rails Models/Associations
  • Tensorflow: how to save/restore a model?
  • SQL query return data from multiple tables

Disclaimer: This content is shared under creative common license cc-by-sa 3.0. It is generated from StackExchange Website Network.

Post navigation

Previous Post:

How to convert DateTime to VarChar

Next Post:

Failed to load the JNI shared Library (JDK)

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

.net ajax android angular arrays aurelia backbone.js bash c++ css dataframe ember-data ember.js excel git html ios java javascript jquery json laravel linux list mysql next.js node.js pandas php polymer polymer-1.0 python python-3.x r reactjs regex sql sql-server string svelte typescript vue-component vue.js vuejs2 vuetify.js

  • you shouldn’t need to use z-index
  • No column in target database, but getting “The schema update is terminating because data loss might occur”
  • Angular – expected call-signature: ‘changePassword’ to have a typedeftslint(typedef)
  • trying to implement NativeAdFactory imports deprecated method by default in flutter java project
  • What should I use to get an attribute out of my foreign table in Laravel?
© 2022 Fix Code Error