If a class is defined in interpreter environment:
class C(object):
def __init__(self, val):
self.x = val
Then instantiated without names:
>>> C(1)
>>> C(2)
>>>
Then we can use underscore _ to refer to C(2)
, so here is my question:
- Since the underscore '_' refer to
C(2)
, can we say the reference
counter for C(2)
is still 1? So the python gc will not free the
memory taken by C(2)
?
- As far as I know, after these
C(2)
is executed, no names will refer to C(1)
, so can I say as soon as C(2)
is executed, C(1)
's
memory will be freed by python gc?
These are actually 4 questions, one bold font to one.
gc: short for garbage collection
EDIT
Let me make my first question more clear by commenting directly into the codes.
>>> C(1) # Press Enter Key and run
>>>
>>> At Here, what is the exact reference count for the previous anonymous object "C(1)"?
>>> And how to prove?
>>>
>>> C(2) # Press Enter Key and run
>>>
>>> At Here, what is the exact reference count for the previous anonymous object "C(1)"?
>>> And how to prove?
C(1)
or C(2)
as last line of the interpreter behaves differently when they are in the middle or to the up of the code.
If C(1)
is at the last line, python interpreter will store it as <__main__.C object at 0x00000000********>
, so actually it will have a name attached to it. If you check number_of_instances(C)
, the result will be 1.
If C(1)
is not at the last line, this temporary anonymous object is just destroyed and disappeared.
Check the following testing codes.
You can use number_of_instances
to show if there is any C
object resides in memory.
import gc
def name_of_instances(cls):
return [obj for obj in gc.get_objects() if isinstance(obj, cls)]
def number_of_instances(cls):
return len([obj for obj in gc.get_objects() if isinstance(obj, cls)])
1.anonymous object not at last line
In [12]: C(1)
...: C(2)
...: print(number_of_instances(C))
...:
0
In [13]:
2.anonymous object at last line
In [6]: C(1)
Out[6]: <__main__.C at 0x6a97ba8>
In [7]: print(number_of_instances(C))
...: print(name_of_instances(C))
...:
1
[<__main__.C object at 0x0000000006A97BA8>]
In [8]: C(2)
Out[8]: <__main__.C at 0x6a9b518>
In [9]: print(number_of_instances(C))
...: print(name_of_instances(C))
...:
2
[<__main__.C object at 0x0000000006A97BA8>, <__main__.C object at 0x0000000006A9B518>]
3.underscore _
will remember C(3)
if it is the last line
In [13]: C(3)
Out[13]: <__main__.C at 0x6aa06d8>
In [14]: type(_)
Out[14]: __main__.C
But in this case, the reference counter never counts reference from _
, it only counts <__main__.C object at 0x0000000006AA06D8>
which you didn't observe.
A guess here: _
is not in gc.garbage
list. If you run C(1)
, print(number_of_instances(C))
successively, number_of_instances
will not check into _
which may be storing the previous C(1)
See: sys.getrefcount continuation
@allen, thank you so much for your answer.
Based on your guess, I made the following code:
In [3]: {'a': 1}
Out[3]: {'a': 1}
In [4]: C(1)
...: print(_)
...: print(type(_))
...: print(number_of_instances(C))
...:
{'a': 1}
<class 'dict'>
0
In [5]:
So the _ underscore is only used for storing the value of last expression in interpreter of "Single Step Mode", not for "Continuous Mode".
This might be a common mistake made by beginners.
Anyway, thank you so much for your answer!