When I type this into the interpreter, calling 'y' seems to invoke the destructor?
class SmartPhone:
def __del__(self):
print "destroyed"
y = SmartPhone()
y #prints destroyed, why is that?
y #object is still there
Here is one run, output does not make sense to me.
C:\Users\z4>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> class SmartPhone:
... def __del__(self):
... print "destroyed"
...
>>> y = SmartPhone()
>>> del y
destroyed
>>> y = SmartPhone()
>>> y
<__main__.SmartPhone instance at 0x01A7CBC0>
>>> y
<__main__.SmartPhone instance at 0x01A7CBC0>
>>> y
<__main__.SmartPhone instance at 0x01A7CBC0>
>>> del y
>>> y = SmartPhone()
>>> y
destroyed
<__main__.SmartPhone instance at 0x01A7CB98>
>>>
and another, calling 'del y' sometimes calls the destructor and sometimes doesn't
C:\Users\z4>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> class SmartPhone:
... def __del__(self):
... print "destroyed"
...
>>>
>>> y = SmartPhone()
>>>
>>> y
<__main__.SmartPhone instance at 0x01B6CBE8>
>>> y
<__main__.SmartPhone instance at 0x01B6CBE8>
>>> y
<__main__.SmartPhone instance at 0x01B6CBE8>
>>> del y
>>> y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> y = SmartPhone()
>>> y
destroyed
<__main__.SmartPhone instance at 0x01B6CC38>
>>> del y
>>> y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>>
Destructors are called when one of the following events occurs: A local (automatic) object with block scope goes out of scope. An object allocated using the new operator is explicitly deallocated using delete . The lifetime of a temporary object ends. A program ends and global or static objects exist.
Create Destructor using the __del__() MethodThis method is automatically called by Python when the instance is about to be destroyed. It is also called a finalizer or (improperly) a destructor.
The best way to not call a particular destructor is to not create an instance of that object to begin with. Failing that, take the code you don't want to run out of the destructor. I can't conceive any reason why doing this would be legitimate.
No. You never need to explicitly call a destructor (except with placement new ). A derived class's destructor (whether or not you explicitly define one) automagically invokes the destructors for base class subobjects. Base classes are destructed after member objects.
The output in question is replicated only in interactive shell.
In interactive session, additional variable _
exists, which refer to last value.
Using sys.getrefcount to inspect reference count:
>>> import sys
>>> class SmartPhone:
... def __del__(self):
... print "destroyed"
...
>>> y = SmartPhone()
>>> sys.getrefcount(y) # not printed, _ does not reference SmartPhone object yet.
2
>>> y
<__main__.SmartPhone instance at 0x000000000263B588>
>>> sys.getrefcount(y) # y printed, _ reference SmartPhone object.
3
2
, 3
in above output should be 1
, 2
. They are printed that way, because getrefcount() increase reference count temporarily as mentioned in getrefcount documentation.
I changed SmartPhone as follow to make it easy to inspect what's going on.
>>> class SmartPhone(object):
... def __init__(self, name):
... self.name = name
... def __repr__(self):
... return super(SmartPhone, self).__repr__() + ' name=' + self.name
... def __del__(self):
... print "destroyed", self
...
>>> y = SmartPhone('first')
>>> del y # deleted immediately, because only "y" reference it.
destroyed <__main__.SmartPhone object at 0x00000000024FEFD0> name=first
>>> y = SmartPhone('second')
>>> y # at this time, _ reference to second y (y's reference count is now 2)
<__main__.SmartPhone object at 0x00000000024FEFD0> name=second
>>> y
<__main__.SmartPhone object at 0x00000000024FEFD0> name=second
>>> y
<__main__.SmartPhone object at 0x00000000024FEFD0> name=second
>>> del y # not deleted immediately, because _ reference it.
>>> y = SmartPhone('third') # _ still reference the second y, because nothing is printed.
>>> y # second y is deleted, because _ now reference the third y. (no reference to the second y)
destroyed <__main__.SmartPhone object at 0x00000000024FEFD0> name=second
<__main__.SmartPhone object at 0x000000000264A470> name=third
You must have reset the value of y
in the same interpreter session, dropping the reference count on the original object to 0. Then, since the first object is not referenced, it gets destroyed, but the new object is referenced by y
>>> class SmartPhone:
... def __del__(self):
... print 'destroyed'
...
>>> y = SmartPhone()
>>> y
<__main__.SmartPhone instance at 0x00000000021A5608>
>>> y = SmartPhone()
>>> y
destroyed
<__main__.SmartPhone instance at 0x00000000021A5648>
Notice that the address of these two objects is different. The destroyed
that is printed is when __del__
is called on the first instance at 0x00000000021A5608
.
In your example, when you explicitly call del
on the object reference, it may be destroyed instantly (if this was the only reference to the object and the GC found it immediately). When you do y = SmartPhone()
the old object will likely not be destroyed immediately, but will be destroyed when the collector finds it and sees a reference count of 0. This usually happens almost immediately but can be delayed.
Your print 'destroyed'
may be displayed immediately or it may display after 1 or more additional commands are executed in your session, but should happen fairly quickly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With