2

The program I ran is

class Account(object):
    counter = 0

    def __init__(self, holder, number, balance, credit_line = 1500):
        Account.counter += 1

    def __del__(self):
        Account.counter -= 1

print "Counter\t", Account.counter
a1 = Account("Homer Simpson", 2893002, 2325.21)
print "Counter\t", Account.counter
a2 = Account("Fred Flintstone", 2894117, 755.32)
print "Counter\t", Account.counter
a3 = a2
print "Counter\t", Account.counter
a4 = Account("Bill Gates", 2895007, 5324.32)
print "Counter\t", Account.counter
del a4
print "Counter\t", Account.counter

The first time I run it the output is correct:

Counter 0
Counter 1
Counter 2
Counter 2
Counter 3
Counter 2

But if I run it again in the same console:

Counter 0
Counter 0
Counter 1
Counter 0
Counter 1
Counter 0

Any idea why the output changes the second time around?

Laura
  • 23
  • 2
  • 1
    How are you running it exactly? – nir0s Mar 10 '17 at 15:21
  • 4
    I think the top answer to this questions talks about the reason behind this http://stackoverflow.com/questions/1481488/what-is-the-del-method-how-to-call-it __del__() gets called when the object gets garbage collected, but isn't reliably called. So in this case, your counter value is inaccurate due to the unreliability of the __del__() method. – chatton Mar 10 '17 at 15:24
  • What @chatton said... but what's the real problem you're trying to address with that `counter` variable? – Jon Clements Mar 10 '17 at 15:30
  • Chatton is right however in this case the garbage collection manages to work fine... It's a really trick but beautiful mash up of references out here :-P.. – Abhishek J Mar 10 '17 at 15:49

1 Answers1

-1

Ahh Got it now!.. Great Problem!..

In the 2nd run:

print "Counter\t", Account.counter   #Class instantiated. Prints 0 
a1 = Account("Homer Simpson", 2893002, 2325.21) #a1 is dereferenced and referenced again!.. 

What Happens above is that a new Account object is created.Thus incrementing the counter. However when a1 references it again at the same previous object referred by it is lost!.. Thus calling del and getting garbage collected reducing count by 1.

print "Counter\t", Account.counter #Thus no change as referencing dereferencing happen together.Prints 0.
a2 = Account("Fred Flintstone", 2894117, 755.32)

Now wait a minute it's going to print 1 next. How is that? What happens above?.. Now remember both a2 and a3 are referencing the same object. When a2 refers the new object the old object is not garbage collected as a3 is still referencing it and thus the increment.

print "Counter\t", Account.counter #Gets incremented and prints 1 as explained above.
a3 = a2

Now you might be getting it ;-).. No new object is created but the last reference of the object was previously referring to is lost as a3 refers to a new object thus decrementing the count.

print "Counter\t", Account.counter #Count decremented print 0 as explained above.
a4 = Account("Bill Gates", 2895007, 5324.32)

A little tricky here but wait. Remember you already deleted a4 in the last run. A brand new object is thus created incrementing the count.

print "Counter\t", Account.counter #count incremented prints 1
del a4

Now you must have got it. Nice question!.. :-D

print "Counter\t", Account.counter

And sorry for the terrible editing. Rather new here and didn't have much time on hand but couldn't restrain from answering :-P

Abhishek J
  • 2,386
  • 2
  • 21
  • 22
  • I don't believe it does. I've copied/pasted the code and ran it several times: each time seeing exactly the same result. Just because the program is run from the same terminal and even referencing the same memory locations, should not show this behavior. With each new instance of the interpreter `counter` is initialized to 0, and each new instance of the object is just that *new*. Unless I have completely misunderstood something, or the OP left out a detail, I don't think this accounts for the behavior. – Andrew Falanga Mar 10 '17 at 16:38
  • Are you also getting the same values as the OP then?.. In the same order when you ran it twice in the same terminal?.. – Abhishek J Mar 10 '17 at 17:02
  • Yes, each time I run the code, I see the first output the OP sees: 0, 1, 2, 2, 3, 2. Interestingly, the only error I see is, after the final print of `Account.counter`: *"'NoneType' object has no attribute 'counter'"* – Andrew Falanga Mar 10 '17 at 17:08
  • But Account is a class.. How come it became None then.. that's weird :-/.. – Abhishek J Mar 10 '17 at 17:13