Rodrigo πŸπŸš€ Profile picture
Take your Python 🐍 skills to the next level πŸš€!

Oct 4, 2021, 26 tweets

What's the deal with Python 🐍's pass-by-value or pass-by-reference?

How does it relate to mutable and immutable objects?

Here's a Python thread πŸ‘‡πŸ§΅ that'll make everything crystal clear and help you master Python 🐍.

Let's go πŸš€

First thing you need to realise is that Python 🐍 does not use the pass-by-value model...

But it also does not use the pass-by-reference model!

Let me see if I can explain what I mean!

What does it mean to pass by value?

In the pass-by-value model, whenever you call a function with a given argument, that argument is fully copied into the function.

This means you can change what got into your function, and you won't be able to see the changes from the outside.

This _looks_ like pass-by-value:

This looks like pass-by-value because we put `a` inside the function, and it had the value `3`.

Then, the function changed to the value `4`...

But outside of the function, `a` is still 3.

This is why it may look like Python uses pass-by-value...

But it doesn't:

And Python does NOT use pass by value because we can do things like this πŸ‘‡

Notice that, in this example, I was able to make a change that reflected outside of the function!

So, is this pass-by-reference..?

This is also _not_ pass-by-reference!

In the pass-by-reference model, the called function would get access to the callee's variables!

Notice this is not what is happening, as I cannot _change_ the variable `l` outside the function πŸ‘‡

Notice how `l` stays the same.

This is different, for example, from this Pascal code πŸ‘‡

The code below outputs the following:

```
2
6
```

Notice how the value of `a` actually changed outside of the function just by means of a simple assignment.

(By the way, you can try this Pascal code by following the link πŸ”— tio.run/##lZAxDsIwDEV3… to the tio.run website.)

Alright, so Python is not pass-by-value and also not pass-by-reference, so what is it..?

Well, in order to understand what Python does, we need to understand well what Python objects are!

By the way, did you know that everything in Python is an object?

Each Python object is characterised by three things...

πŸ‘‰ its identity (an integer that identifies your object, just like your social security number);
πŸ‘‰ a type (that identifies what operations you can do with your ojbect); and
πŸ‘‰ some content;

Here's an example πŸ‘‡

Now, what might be tricky here, is that the β€œname” `obj` has NOTHING to do with the object itself.

The three letters β€œobj” were just a label that I attached to the object with identity 2698212637504, type list, and contents 1, 2, 3.

I can attach many names to it πŸ‘‡

But these names are just labels I put on the exact same object.

How can I know it's the exact same object?

Well, all their β€œsocial security numbers” match πŸ‘‡

Therefore, these labels all point to the same name...

So...

Oh, and by the way, this is what the `is` operator does in Python 🐍!

It checks to see if two labels (two names) are pointing at the _same_ object.

In other words, it checks if the identities of the two operands are the same!

So this is what assignment does: it just sticks a new label – a new name – onto an object.

It's pretty much like a nickname!

I have plenty of different nicknames, but regardless of what you call me, or what my mom calls me, I'm always the same person, right..?

Therefore, if I change, everyone sees the change, not just my mom, or not just my friends, or not just you!

So, if I mutate the _contents_ of the list we had previously...

Then all the nicknames should be able to tell that something is different πŸ‘‡

Now, at this point, the identity of the object did NOT change!

It's still the same object!

It's just that its contents changed a bit.

Much like you can change your clothes, or have different thoughts.

That's because a list is a _mutable_ object..!

_Mutable_ means that it can be mutated – that it can be changed (internally).

Some other Python types are _immutable_, which means they cannot be modified internally.

A good example of that is the `tuple` type.

If you create a `tuple`, you can't change its elements πŸ‘‡

Thus, with immutable data types (like tuples, strings, integers, floats) you can only _build_ new objects, you cannot modify them internally.

It's like that VERY stubborn friend of yours.

It's always the same object, and their contents don't change πŸ˜‚

Ok, cool, but so what? πŸ€ͺ

When you call a function in Python, the model you use is β€œpass-by-assignment”.

This means that the parameters of the function just become new labels to the objects you gave as arguments.

How can we tell this..?

If you've been paying attention, you should know by now!

You can check that it's the same objects, just with a different label, because the identity of the objects is the same.

Here's a function that prints the identity of its only argument πŸ‘‡

As you could see, being (im)mutable didn't matter: when we call `foo`, β€œx” just becomes a new label to the exact same object we had _outside_ of the function.

So that means the following:

― if you give mutable objects to your function, your function can change the inner contents of your objects.

That's what sometimes trips people up.

The classical examples in Python 🐍 are lists and dictionaries.
Careful when using them inside your function πŸ‘‡

I think this is it for this thread πŸ˜‰ In < 24 hours I will publish a Pydon't on my blog (mathspp.com/blog/pydonts) with all this information, more examples, and also all the sources.

This way you'll be able to do some research on your own, as well.

If you like the way I explain these interesting Python 🐍 concepts, and you'd like more...

Make sure to follow me (@mathsppblog) to not miss a single drop of knowledge I share!

I would also love it if you could retweet the beginning of this thread πŸ’ͺπŸ”₯:

I hope that you found this thread very informative, and I'll gladly take any questions you might have πŸ‘‡πŸ’¬

Here's a TL;DR:

πŸ‘‰ python uses pass-by-assignment (not pass-by-value, not pass-by-reference);
πŸ‘‰ all objects have 3 different characteristics: an id, a type, contents;

πŸ‘‰ `is` checks if two names point to the same object;
πŸ‘‰ when calling functions, parameters become labels to the objects that were passed in;
πŸ‘‰ for mutable objects (that can have their contents changed), the function can make changes that are visible from the outside.

Bye πŸ‘‹

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling