Reputation: 329
I was experimenting with id to understand default values in python
def f(x=5000):
print(id(x))
x=40000
print(id(x))
print()
f()
f()
This gives the output
2187265500336
2187265501488
2187265500336
2187265501488
I understand why the first print statements are the same. This is because the default value x is evaluated when the function is defined.
However, that in both cases the second print statement gives the same id is confusing me and I couldn't find an answer online elsewhere. Consider
a=100000
print(id(a))
a=400000
print(id(a))
a=100000
print(id(a))
a=400000
print(id(a))
this gives the output
2187265558768
2187265558608
2187265559440
2187265558032
What is causing the difference in the two cases? Inside the function, when we reassign the variable in different function calls, it gets the same id, yet when we reassign a variable to the same value as previously outside a function, this doesn't occur
EDIT in response to @Barmar's comment and the question linked understanding python id() uniqueness. I somewhat understand, but not fully. My best guess now would be (1) the memory is left free for future use as said in the comment (2) in the example below, there seems to be some underlying reason why the same memory gets assigned to x each time even when other memory is assigned. Is this because of caching optimisations,
Caching optimizations mean that you are not always guaranteed to get a new object in cases where one might naiively think one should, but this does not in any way violate the uniqueness guarantee of IDs. Builtin types like int and str may have some caching optimizations, but they follow exactly the same rules: If they are live at the same time, and their IDs are the same, then they are the same object.
def f(x=5000):
print(id(x))
c=23000
d=12444
x=40000
w=23444
print(id(x))
print()
f()
f()
2187265559440
2187265559376
2187265559440
2187265559376
Here we assign several new variables, but each time the same id gets assigned to the variable x upon reassignment.
Regarding @dont just talk code's comment
It probably will, if you just try it a few more times.
I then tried this with the following, but the same result held when repeated a million times
def f(x=5000):
id_1 = id(x)
c=23000
d=12444
x=40000
w=23444
id_2 = id(x)
return (id_1, id_2)
[f() for n in range(1000000)] == [f() for n in range(1000000)]
True
Upvotes: 0
Views: 131
Reputation: 51037
Constants inside a function come from the function's code object's co_consts
attribute.
>>> f.__code__.co_consts
(None, 40000)
>>> id(f.__code__.co_consts[1])
140572403241776
>>> f()
140572374132688
140572403241776
So the second int
object with the value 40000
is also created at the function definition, not during the function call.
This is a CPython implementation detail, because all details about CPython bytecode and code objects are CPython implementation details.
Upvotes: 5