there is no answer to the point upstairs. This phenomenon is related to gc and belongs to undefined behavior.
here's the thing:
When
executes zhuangshi (A) is zhuangshi (A)
, the expression evaluates from left to right, first computes the first zhuangshi (A)
, and assumes that the return value has a temporary variable, assuming tmp1
, and then calculates the second, and the return value exists tmp2
. There are actually two copies of inner
in memory, each pointing to a reference tmp1
tmp2
, and their addresses are of course different, so the result of is
is False
.
look at the second example:
When
executes id (zhuangshi (A)) = = id (zhuangshi (A))
, the expression evaluates from left to right and from the inside out. We first compute zhuangshi (A)
, then pass the return value to id
, and finally we get an integer. Note that unlike the previous example, there are no references to inner, so the garbage collector can recycle it . When the second expression is evaluated, there is a certain probability that Python will create a new inner object at the address of the previous inner object, resulting in the two addresses being the same.
all in all, it looks like they are the same object, but in fact they are two different objects created successively at the same address, so they have the same id.
print(zhuangshi(A) is zhuangshi(A))
a, b = zhuangshi(A), zhuangshi(A)
print(a is b) -sharpFalse
print(id(a) == id(b)) -sharpFalse
print(id(zhuangshi(A)) == id(zhuangshi(A)))
a, b = id(zhuangshi(A)), id(zhuangshi(A))
print(a == b) -sharpTrue idtrue
= = is to compare whether the values of two objects are equal.
is in addition to comparing whether the values of objects are equal, it also involves comparing the memory addresses of two objects if they are equal.
>>> type(zhuangshi(A))
<class 'function'>
>>> zhuangshi(A)
<function zhuangshi.<locals>.inner at 0x7f7823a98b70> -sharp
>>> zhuangshi(A)
<function zhuangshi.<locals>.inner at 0x7f78208ac7b8> -sharp
>>> c, d = A, A
>>> type(c)
<class 'type'>
>>> type(d)
<class 'type'>
>>> c
<class '__main__.A'>
>>> d
<class '__main__.A'>
>>>
>>> c is d
True
>>>
to sum up, it is clear that the zhuangshi class defines the return of an inner object, and the inner function is executed once for each call, so the memory address of the call is different.