Skip to content

Docs: clarify object assignments intuition in the tutorial section #116271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Privat33r-dev opened this issue Mar 3, 2024 · 12 comments
Closed

Docs: clarify object assignments intuition in the tutorial section #116271

Privat33r-dev opened this issue Mar 3, 2024 · 12 comments
Assignees
Labels
docs Documentation in the Doc dir

Comments

@Privat33r-dev
Copy link
Contributor

Privat33r-dev commented Mar 3, 2024

Documentation

In the Tutorial section of the Python Documentation, 2 parts (introduction and datastructures) are explaining lists and none of them go deeper in the concept of mutability in Python: lists (or other mutable) assignments are just essentially a pointer assignments and they do not create a new object, but rather create another reference to the same object, which might lead to unexpected results.

>>> rgb = ['red', 'green', 'blue']
>>> rgba = rgb
>>> rgba.append('alpha')`
>>> 'alpha' in rgb
True # Unexpected!
>>> id(rgb) == id(rgba) 
True # Explains the nature

Mentions

@nedbat gave an advice regarding better positioning of the in the IRC channel

Sidenote

While researching this topic, I found a Google's paper on the topic that starts introduction to the list concept with this peculiarity.

Linked PRs

@Privat33r-dev Privat33r-dev added the docs Documentation in the Doc dir label Mar 3, 2024
@Privat33r-dev Privat33r-dev changed the title Docs: Mutability concept remain unexplained Docs: Mutability concept remains unexplained Mar 3, 2024
@nedbat
Copy link
Member

nedbat commented Mar 3, 2024

It's important to note that assignment always behaves the same. Mutability does not change how assignment works. Assignment never copies data, it only makes another name refer to an existing value.

@pochmann3
Copy link
Contributor

they do not create a new object

Why would anyone even think that they do?

Honestly that's been puzzling me for quite a while, every time I see people making that mistake. Maybe you have some insights?

@nedbat
Copy link
Member

nedbat commented Mar 3, 2024

Why would anyone even think that they do?

This is a very common mistake. People see the behavior of x = 1; y = x; x = 2 and think it makes a copy. Also, C has struct assignment that copies the contents of one struct to another.

It might be hard for experts in Python to understand the beginner mindset. Trust me: this is very common.

@Privat33r-dev
Copy link
Contributor Author

Why would anyone even think that they do?

Honestly that's been puzzling me for quite a while, every time I see people making that mistake. Maybe you have some insights?

I will answer with code:

pi = 3.14
tmp = pi
tmp += 1
pi == 3.14 # as expected, remained the same

And the same thing with other immutable objects.

Python's definition of mutability states that mutable objects can be changed without changing their ID:

tmp = {}
tmp_id = id(tmp)
tmp['popular_cheese'] = ""
tmp == {'popular_cheese': 'Illchester'} # expected
tmp_id == id(tmp) # expected as well

How should the reference assignment derive from it is still beyond my comprehension :)

As well we have another thing that according to Diataxis we shouldn't presume that the reader possesses any special knowledge.

@Privat33r-dev
Copy link
Contributor Author

It's important to note that assignment always behaves the same. Mutability does not change how assignment works. Assignment never copies data, it only makes another name refer to an existing value.

That's an interesting point. Is there a way to introduce primitive and reference types to the reader? It looks like a mirrored concept with mutability.

Do you have counter-examples with mutable primitives or immutable reference types?

@nedbat
Copy link
Member

nedbat commented Mar 3, 2024

@Privat33r-dev your original suggestion (in IRC) was to show an example using lists to warn people that copy = data doesn't make a copy. Expanding out to the generalized concepts might be more complex.

BTW: Python doesn't have primitive and reference types either (Java does). All values are objects, and assignment treats all values the same.

@pochmann3
Copy link
Contributor

This is a very common mistake.

I know. I've probably seen it hundreds of times.

And I think many times it was people who mentioned they just started programming, so they weren't applying misleading knowledge from another language. I can somewhat follow the reasoning with experience from numbers, and with += it's at least the same syntax. But when people see with lists that it clearly doesn't make a copy, why are they so perplexed and can't figure it out? Why are there thousands of questions about that on Stack Overflow?

I think assuming a copy is made is unnatural. That's not happening in the real world. Things don't magically duplicate. If I get a cat and start calling it Bernie, I don't have two cats. If I called someone's dog Alex and then killed Alex, that other person would be angry. Because it's the same dog. And people have lots of experience with the real world. Why does that vast experience not translate?

@nedbat
Copy link
Member

nedbat commented Mar 3, 2024

But when people see with lists that it clearly doesn't make a copy, why are they so perplexed and can't figure it out? Why are there thousands of questions about that on Stack Overflow?

I'm not sure what to tell you other than the two numeric examples that we've shown here in this discussion.

Do you agree that it would be useful to show that assigning lists doesn't make a copy? I suggested it could go here https://docs.python.org/3/tutorial/introduction.html#lists right before "Assignment to slices is also possible."

@Privat33r-dev
Copy link
Contributor Author

But when people see with lists that it clearly doesn't make a copy, why are they so perplexed and can't figure it out? Why are there thousands of questions about that on Stack Overflow?

I'm not sure what to tell you other than the two numeric examples that we've shown here in this discussion.

Do you agree that it would be useful to show that assigning lists doesn't make a copy? I suggested it could go here https://docs.python.org/3/tutorial/introduction.html#lists right before "Assignment to slices is also possible."

I had to move the shallow copy part because I don't have introduced tools to show how mutation of the first object affect the other. Currently working on the PR (btw, you can assign me to the issue :) )

@pochmann3
Copy link
Contributor

Do you agree that it would be useful to show that assigning lists doesn't make a copy?

I guess it would be, yes. But I hope it'll be phrased better than in Google's class, which in my opinion makes it sound like assignment with lists is special.

@Privat33r-dev Privat33r-dev changed the title Docs: Mutability concept remains unexplained Docs: clarify object assignments intuition in the tutorial section Mar 3, 2024
hugovk added a commit that referenced this issue Mar 4, 2024
…utorial section (#116283)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 4, 2024
… the Tutorial section (pythonGH-116283)

(cherry picked from commit 45a9243)

Co-authored-by: Kerim Kabirov <[email protected]>
Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Mar 4, 2024
… the Tutorial section (pythonGH-116283)

(cherry picked from commit 45a9243)

Co-authored-by: Kerim Kabirov <[email protected]>
Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
hugovk added a commit that referenced this issue Mar 4, 2024
…n the Tutorial section (GH-116283) (#116306)

Co-authored-by: Kerim Kabirov <[email protected]>
Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
hugovk added a commit that referenced this issue Mar 4, 2024
…n the Tutorial section (GH-116283) (#116305)

Co-authored-by: Kerim Kabirov <[email protected]>
Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
@hugovk
Copy link
Member

hugovk commented Mar 4, 2024

Thank you for the issue and PR!

@hugovk hugovk closed this as completed Mar 4, 2024
woodruffw pushed a commit to woodruffw-forks/cpython that referenced this issue Mar 4, 2024
… the Tutorial section (python#116283)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
adorilson pushed a commit to adorilson/cpython that referenced this issue Mar 25, 2024
… the Tutorial section (python#116283)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
diegorusso pushed a commit to diegorusso/cpython that referenced this issue Apr 17, 2024
… the Tutorial section (python#116283)

Co-authored-by: Ned Batchelder <[email protected]>
Co-authored-by: Hugo van Kemenade <[email protected]>
@Privat33r-dev
Copy link
Contributor Author

they do not create a new object

Why would anyone even think that they do?

Honestly that's been puzzling me for quite a while, every time I see people making that mistake. Maybe you have some insights?

I have another interesting answer for your question. COW. As in the C++ example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

No branches or pull requests

4 participants