15.04.2013 Views

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

id(c1), id(c2), id(c3) # all refer to same object<br />

(11938912, 11938912, 11938912)<br />

>>> del c1 # remove one reference<br />

>>> del c2 # remove another reference<br />

>>> del c3 # remove final reference<br />

deleted # destructor finally invoked<br />

Notice how, in the above example, the destructor was not called until all references to the instance of<br />

class C were removed, e.g., when the reference count has decreased to zero. If for some reason your<br />

__del__() method is not being called when you are expecting it to be invoked, this means that somehow<br />

your instance object's reference count is not zero, and there may be some other reference to it that you<br />

are not aware of that is keeping your object around.<br />

Also note that the destructor is called exactly once, the first time the reference count goes to zero and<br />

the object deallocated. This makes sense because any object in the system is allocated and deallocated<br />

only once. Summary:<br />

● Do not forget to call a superclass __del__() first.<br />

● Invoking del x does not call x.__del__()as you saw above, it just decrements the reference count<br />

of x.<br />

● If you have a cycle or some other cause of lingering references to an instance, an object's __del__<br />

() may never be called.<br />

● Uncaught exceptions in __del__() are ignored (because some variables used in __del__() may<br />

have already been deleted). Try not to do anything in __del__() not related to an instance.<br />

● Implementing __del__() is not a common occurrenceonly do it if you really know what you are<br />

doing.<br />

● If you define __del__, and instance is part of a cycle, the garbage collector will not break the<br />

cycleyou have to do it yourself by explicitly using del.<br />

<strong>Core</strong> Note: Keeping track of instances<br />

<strong>Python</strong> does not provide any internal mechanism to track how many<br />

instances of a class have been created or to keep tabs on what they<br />

are. You can explicitly add some code to the class definition and<br />

perhaps __init__() and __del__() if such functionality is desired. The<br />

best way is to keep track of the number of instances using a static<br />

member. It would be dangerous to keep track of instance objects by<br />

saving references to them, because you must manage these<br />

references properly or else your instances will never be deallocated<br />

(because of your extra reference to them)! An example follows:<br />

class InstCt(object):<br />

count = 0 # count is class attr<br />

def __init__(self): # increment count<br />

InstCt.count += 1<br />

def __del__(self): # decrement count<br />

InstCt.count -= 1<br />

def howMany(self): # return count<br />

return InstCt.count<br />

>>> a = InstTrack()

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!