Avoiding Side Effects
Now that you know how to use the
return statement, let’s look at side effects again and see how a Python program would do some of the actions that we would perform using side effects in other languages.
00:13 For example, suppose that you want to write a function that takes a number and doubles that number. In C++, it would look something like this. We would use pass-by-reference and it would take that object, that variable, and it would actually double its value.
x, although in a different scope, is actually referring to the same
x that this is. It’s being doubled. This is pass-by-reference, so we can see—or we will see after calling this function—it has been given a value of
the ampersand (
&) I used up here indicates that we are passing by reference. The function has direct access to this variable
x, and so when it changes
x up here, that change is seen down here in the function. Python doesn’t have pass-by-reference, and so if we tried writing that as a function…
At the beginning, we’ve already seen that
x does refer to the same integer object
5, but when I reassign it, it forgets all about that object and creates a new object and has
x refer to that. So in this environment,
x is still
5. But what if that’s what you want?
So if we want to double the value of
x, knowing that in this instance we’re doing pass-by-value, the only thing that we can do is apply this function, which now returns the modified value, and then save that back into the variable where it started, so now it has the value of
03:31 So, what you would want to do as a side effect using pass-by-reference in another language doesn’t work in Python. So you perform the calculation necessary and then return that value and then know when you are using this type of function to save the value returned back to the same variable. And that’s especially the case if you are using an immutable object.
But we do know that lists are mutable, So I could create a function called
double_list(), and there are two versions of this, so I’ll call this
double_list1(), where I take my list and then as I propagate through the list, I multiply each value by
2 and save it back to that same value in the list.
And because a list in Python is mutable, this will work. So let me come back here, and I called this module
doubler1, so from
doubler1, we’re going to import everything. That’s the only thing that’s there.
05:19 And so instead of modifying the parameter, creating side effects, maybe what we would prefer is to create a new list where each value in the new list is double the corresponding element in the previous list and then return it.
And so that’s the version in what I’ve called
doubler2. I create a new list and as I propagate through the list, I append to it a new value formed by the current value of the original list multiplied by
2, and then I return it.
I called this
double_list2(). I say
a is the parameter. Since
a isn’t modified by this function, I need to save the return value back to
a, and this would be the more common way to make this happen.
06:48 And so to avoid the use of side effects, when we want to modify an object in our function we should create a new object with the appropriate parameters, return that object, and then know in the calling environment just to save that back to the original variable.
Become a Member to join the conversation.