+ 3

[Solved. Garbage collection.] Why first id() again?

I don't understand this behavior. Does anyone else? Please cite sources if possible. https://sololearn.com/compiler-playground/c968j9DmVWid/?ref=app

6th Jan 2024, 11:18 AM
Rain
Rain - avatar
5 odpowiedzi
+ 6
As far as I know functions are objects in Python. https://realpython.com/lessons/object-value-vs-object-identity/#:~:text=In%20Python%2C%20every%20object%20that,in%20which%20their%20lifetimes%20overlap. "In Python, every object that is created is given a number that uniquely identifies it. It is guaranteed that no two objects will have the same identifier during any period in which their lifetimes overlap." https://www.digitalocean.com/community/tutorials/python-id "Two objects with non-overlapping lifetimes may have the same id() value." From this I conclude that the first function is swallowed by the garbage collector after the same function has been created a third time. If the first function still existed in memory, the third function would otherwise have to be given a new id. However, I find the question of why all three functions are not given the same id more interesting.
6th Jan 2024, 2:10 PM
Denise Roßberg
Denise Roßberg - avatar
+ 5
# an extended version for i in range(10): def fun(): pass print(f"{i} -- {id(fun)}") I could imagine that Python 1. puts the new definition in memory and then 2. checks if there is a collision with another function (and then overwrites the reference). That would explain why there are 2 different ids.
6th Jan 2024, 12:59 PM
Lisa
Lisa - avatar
+ 4
We should also consider that we tested a rather simple case, so it may not be as reliable in larger or more complex programs.
6th Jan 2024, 7:00 PM
Lisa
Lisa - avatar
+ 3
Denise Roßberg , Gotcha. I think for all three objects to have the same id, garbage collection would have to interrupt the assignment, delete the previous object, garbage collect it, make the memory available again, and continue the assignment. That kind of oversight would require a constantly running "watcher" routine capable of interrupting any operation, which would slow everything down. However, I modified Lisa's loop to add an explicit del() statement (which removes one reference, the only reference in this case), and it reused the same id all 10 times as you were imagining. Garbage collection was able to make the no-longer-referenced memory available again between the del statement and the next loop iteration without needing to interrupting any operation. # reuse same id for i in range(10): def fun(): pass print(f"{i} -- {id(fun)}") del(fun)
6th Jan 2024, 7:06 PM
Rain
Rain - avatar
+ 2
Lisa , Thanks for the extended test. I see that the two id numbers keep getting reused. That proves that, at least in the CPython implementation (used by Sololearn, Pydroid 3, and probably the majority of places), garbage collection is both fast and efficient. From what I had previously read on python.org, I thought garbage collection was unreliable, and I didn't even think to consider it. "An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable." -- https://docs.python.org/3/reference/datamodel.html#objects-values-and-types Now I know it's good in CPython.
6th Jan 2024, 6:49 PM
Rain
Rain - avatar