Wednesday, November 3, 2021

"Mathspp Pydon'ts": Pass-by-value, reference, and assignment | Pydon't 🐍

When you call a function in Python and give it some arguments... Are they passed by value? No! By reference? No! They're passed by assignment.

Python snippet containing the code `x is y`.

(If you are new here and have no idea what a Pydon't is, you may want to read the Pydon't Manifesto.)

Introduction

Many traditional programming languages employ either one of two models when passing arguments to functions:

  • some languages use the pass-by-value model; and
  • most of the others use the pass-by-reference model.

Having said that, it is important to know the model that Python uses, because that influences the way your code behaves.

In this Pydon't, you will:

  • see that Python doesn't use the pass-by-value nor the pass-by-reference models;
  • understand that Python uses a pass-by-assignment model;
  • learn about the built-in function id;
  • create a better understanding for the Python object model;
  • realise that every object has 3 very important properties that define it;
  • understand the difference between mutable and immutable objects;
  • learn the difference between shallow and deep copies; and
  • learn how to use the module copy to do both types of object copies.

You can now get your free copy of the ebook “Pydon'ts – Write beautiful Python code” on Gumroad.

Is Python pass-by-value?

In the pass-by-value model, when you call a function with a set of arguments, the data is copied into the function. This means that you can modify the arguments however you please and that you won't be able to alter the state of the program outside the function. This is not what Python does, Python does not use the pass-by-value model.

Looking at the snippet of code that follows, it might look like Python uses pass-by-value:

def foo(x):
    x = 4

a = 3
foo(a)
print(a)
# 3

This looks like the pass-by-value model because we gave it a 3, changed it to a 4, and the change wasn't reflected on the outside (a is still 3).

But, in fact, Python is not copying the data into the function.

To prove this, I'll show you a different function:

def clearly_not_pass_by_value(my_list):
    my_list[0] = 42

l = [1, 2, 3]
clearly_not_pass_by_value(l)
print(l)
# [42, 2, 3]

As we can see, the list l, that was defined outside of the function, changed after calling the function clearly_not_pass_by_value. Hence, Python does not use a pass-by-value model.

Is Python pass-by-reference?

In a true pass-by-reference model, the called function gets access to the variables of the callee! Sometimes, it can look like that's what Python does, but Python does not use the pass-by-reference model.

I'll do my best to explain why that's not what Python does:

def not_pass_by_reference(my_list):
    my_list = [42, 73, 0]

l = [1, 2, 3]
not_pass_by_reference(l)
print(l)
# [1, 2, 3]

If Python used a pass-by-reference model, the function would've managed to completely change the value of l outside the function, but that's not what happened, as we can see.

Let me show you an actual pass-by-reference situation.

Here's some Pascal code:

program callByReference;
var
    x: integer;...


from Planet Python
via read more

No comments:

Post a Comment

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...