6

I'm trying to understand this code:

class Person:
    '''Represents a person '''
    population = 0

    def __init__(self,name):
          //some statements and population += 1
    def __del__(self):
          //some statements and population -= 1 
    def sayHi(self):
        '''grettings from person'''
        print 'Hi My name is %s' % self.name

    def howMany(self):
        '''Prints the current population'''
        if Person.population == 1:
            print 'i am the only one here'
        else:
            print 'There are still %d guyz left ' % Person.population
rohan = Person('Rohan')
rohan.sayHi()
rohan.howMany()


sanju = Person('Sanjivi')
sanju.howMany()

del rohan # am i doing this correctly? 

How does the destructor get invoked -- automatically or do I have to add something in the "main" program/class like above?

Output:

Initializing person data
******************************************
Initializing Rohan
******************************************
Population now is: 1
Hi My name is Rohan
i am the only one here
Initializing person data
******************************************
Initializing Sanjivi
******************************************
Population now is: 2
In case Person dies:
******************************************
Sanjivi Bye Bye world
there are still 1 people left
i am the only one here
In case Person dies:
******************************************
Rohan Bye Bye world
i am the last person on earth
Population now is: 0

If required I can paste the whole lesson as well. I'm learning from: http://www.ibiblio.org/swaroopch/byteofpython/read/

trincot
  • 317,000
  • 35
  • 244
  • 286
rgolwalkar
  • 71
  • 1
  • 2
  • 6
  • Please learn to use the indentation required for code examples. – S.Lott Mar 12 '10 at 14:26
  • What is your question? If you could summarize your question, it would help us answer. If that book isn't helpful there are dozens of others that might be more helpful. – S.Lott Mar 12 '10 at 14:28
  • Correct me if I'm wrong, but I think he wanted someone to explain constructors and deconstructors to him in plain English. Just a hunch. – dclowd9901 Mar 12 '10 at 14:35
  • Like dclowd9901 said i want someone to explain constructors and deconstructors in English --- i am sorry if i was not clear -- i am very new to programming -- any help is appreciated. – rgolwalkar Mar 12 '10 at 14:50
  • "explain" is vague -- it could mean anything. It could mean "explain how it's implemented by the compiler" or "explain how it maps to a relational database" or "explain why this code doesn't work" or "explain why I even care about OO design". I'm sorry for being dense, but "explain" seems open-ended and hard to answer. – S.Lott Mar 12 '10 at 15:03
  • The question lacks actual question. You could also write 'Can someone here explain me Python programming?' and paste some other random Python code – it would be as pointless as this one is. – Jacek Konieczny Mar 12 '10 at 15:08
  • i have pasted the code above and i am seeking explaination to how destructor gets invoked -- automatically or do i have to something in the "main" program/class ? – rgolwalkar Mar 12 '10 at 15:35
  • @rgolwalkar: "how destructor gets invoked -- automatically or do i have to something in the "main" program/class ?" **Great question**. Now, please **update** your question to have a proper title and this question. Consider eliminating the execution trace to focus on **only** your question. – S.Lott Mar 12 '10 at 15:41
  • The long comment thread and immediate dislike of the question is a natural reaction to `__del__`, and not the question. "Explain `__del__`" makes grown programmers cry. – Charles Merriam Mar 12 '10 at 15:48

2 Answers2

23

Here is a slightly opinionated answer.

Don't use __del__. This is not C++ or a language built for destructors. The __del__ method really should be gone in Python 3.x, though I'm sure someone will find a use case that makes sense. If you need to use __del __, be aware of the basic limitations per http://docs.python.org/reference/datamodel.html:

  • __del__ is called when the garbage collector happens to be collecting the objects, not when you lose the last reference to an object and not when you execution del object.
  • __del__ is responsible for calling any __del__ in a superclass, though it is not clear if this is in method resolution order (MRO) or just calling each superclass.
  • Having a __del__ means that the garbage collector gives up on detecting and cleaning any cyclic links, such as losing the last reference to a linked list. You can get a list of the objects ignored from gc.garbage. You can sometimes use weak references to avoid the cycle altogether. This gets debated now and then: see http://mail.python.org/pipermail/python-ideas/2009-October/006194.html.
  • The __del__ function can cheat, saving a reference to an object, and stopping the garbage collection.
  • Exceptions explicitly raised in __del__ are ignored.
  • __del__ complements __new__ far more than __init__. This gets confusing. See http://www.algorithm.co.il/blogs/index.php/programming/python/python-gotchas-1-del-is-not-the-opposite-of-init/ for an explanation and gotchas.
  • __del__ is not a "well-loved" child in Python. You will notice that sys.exit() documentation does not specify if garbage is collected before exiting, and there are lots of odd issues. Calling the __del__ on globals causes odd ordering issues, e.g., http://bugs.python.org/issue5099. Should __del__ called even if the __init__ fails? See http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423 for a long thread.

But, on the other hand:

And my pesonal reason for not liking the __del__ function.

  • Everytime someone brings up __del__ it devolves into thirty messages of confusion.
  • It breaks these items in the Zen of Python:
    • Complex is better than complicated.
    • Special cases aren't special enough to break the rules.
    • Errors should never pass silently.
    • In the face of ambiguity, refuse the temptation to guess.
    • There should be one-- and preferably only one --obvious way to do it.
    • If the implementation is hard to explain, it's a bad idea.

So, find a reason not to use __del__.

Charles Merriam
  • 19,908
  • 6
  • 73
  • 83
  • 2
    Awesome Charles -- though it was more technical but i understand it better now -- one last question -- when i create an object -- does it really ever get destoryed/Freed ? And Like you said not to use __del__ would it be a better idea to just make some tiny function and get it to work as i want it in the output ? thanks again in advance – rgolwalkar Mar 12 '10 at 16:00
  • After much thought, I'ld have to say I don't know. If the object were not declared at the top level then it would be collected. Top level objects are less clear. Sorry. – Charles Merriam Mar 16 '10 at 08:26
  • Thanks Charles - you've been a great help – rgolwalkar Apr 05 '10 at 14:19
  • Note that currently, since python3.4+ with the introduction of [PEP 442](https://docs.python.org/3/whatsnew/3.4.html#pep-442-safe-object-finalization), the GC **is** able to call `__del__` on *most* cycles. You should update your answer regarding that point. – Bakuriu Jun 16 '16 at 07:37
  • Sorry, would "the GC guess when to call __del__ on versions of Python 3.4+" be correct? – Charles Merriam Jul 01 '16 at 21:57
1

As I understood them from my early CPTS experiance:

Constructors: Constructors are mainly used in classes to initialze the class with values, and gives an oppurtunity to do some background work based on creation. If you pass in values during the creation of an object, this is where you can handle assignment of those values to variables within your class. (In this case, upon construction you are incrementing a variable that keeps track of population).

Destructors: Destructors cleanup a class. In python, due to the garbage collector it's not as important as languages that can leave hanging pointers (c++). (In this case you are decrementing the population variable on destruction of the object).

Hortinstein
  • 2,667
  • 1
  • 22
  • 22
  • Thanks Hortinstein for nice and simple explanation -- so what i have writtens makes sense ?? did i use the "del rohan" - delete the object so a Destructors is called ?? – rgolwalkar Mar 12 '10 at 14:56
  • 5
    No, `del rohan` will *not* invoke the destructor. It will decrement the reference count on the `rohan` object and remove the name from that scope. *If* the reference count hits 0 *then* the destructor will be called. It's a subtle but important distinction. – Ignacio Vazquez-Abrams Mar 12 '10 at 15:10
  • hmm so if i don't use del rohan -- my destructor def __del__(self) will not get executed at all ?? asking this because earlier i did not use del at all and so def __del__(self) did not take any effect -- correct me if i am wrong - because i am not getting a clear understanding of whether this destructor will invole itself ever or not if don;t use del – rgolwalkar Mar 12 '10 at 15:30