473,382 Members | 1,615 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

initializing class with certain names causes runtime errors

Hello, I am new to programming with python. I am using the tutorial, "Byte of Python" and am on p. 82. I have come across something very unusual by accident and I was wondering if anybody here could figure it out. In the program attached, if I use "wanless.sayHI()" which is my name,python gives an error message.........Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb76056ec>> ignored..... Any of the commented out groups of code do the same. I was looking for a bad indent or missing ' or anything for about an hour. Once I figured it out I thought is was so funny I had to send it to someone who knows python just to see what you think of it. I used both "Idle using Python2.6.2", and gedit 2.26.1, to create the program and I get the same results with either one. I use Ubuntu 9.04 the original program is from the book "Byte of Python" p.82 2003-2005 edition

result of program as is

Expand|Select|Wrap|Line Numbers
  1. (Initializing Swaroop)
  2. Hi, my name is Swaroop.
  3. I am the only person here.
  4. (Initializing less)
  5. Hi, my name is less.
  6. We have 2 persons here.
  7. (Initializing wanles)
  8. Hi, my name is wanles.
  9. We have 3 persons here.
  10. Hi, my name is Swaroop.
  11. We have 3 persons here.
  12. wanles says bye.
  13. There are still 2 people left.
  14. less says bye.
  15. There are still 1 people left.
  16. Swaroop says bye.
  17. I am the last one.
  18.  
result of code with block 1 uncommented

Expand|Select|Wrap|Line Numbers
  1. (Initializing Swaroop)
  2. Hi, my name is Swaroop.
  3. I am the only person here.
  4. (Initializing wanless)
  5. Hi, my name is wanless.
  6. We have 2 persons here.
  7. (Initializing less)
  8. Hi, my name is less.
  9. We have 3 persons here.
  10. (Initializing wanles)
  11. Hi, my name is wanles.
  12. We have 4 persons here.
  13. Hi, my name is Swaroop.
  14. We have 4 persons here.
  15. wanles says bye.
  16. There are still 3 people left.
  17. less says bye.
  18. There are still 2 people left.
  19. Swaroop says bye.
  20. There are still 1 people left.
  21. wanless says bye.
  22. Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb766f48c>> ignored
  23.  
the code is exactly the same as the book down to line 35


Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/python
  2. # Filename: objvar.py
  3. #          Mark Wanless
  4.  
  5. class Person:
  6.         '''Represents a person.'''
  7.         population = 0
  8.         def __init__(self, name):
  9.                 '''Initializes the person's data.'''
  10.                 self.name = name
  11.                 print '(Initializing %s)' % self.name
  12.                 # When this person is created, he/she
  13.                 # adds to the population
  14.                 Person.population += 1
  15.         def __del__(self):
  16.                 '''I am dying.'''
  17.                 print '%s says bye.' % self.name
  18.                 Person.population -= 1
  19.                 if Person.population == 0:
  20.                          print 'I am the last one.'
  21.                 else:
  22.                          print 'There are still %d people left.' % Person.population
  23.         def sayHi(self):
  24.                 '''Greeting by the person.
  25.                 Really, that's all it does.'''
  26.                 print 'Hi, my name is %s.' % self.name
  27.         def howMany(self):
  28.                 '''Prints the current population.'''
  29.                 if Person.population == 1:
  30.                          print 'I am the only person here.'
  31.                 else:
  32.                          print 'We have %d persons here.' % Person.population
  33. swaroop = Person('Swaroop')
  34. swaroop.sayHi()
  35. swaroop.howMany()
  36.  
  37. less = Person('less') ### no problem
  38. less.sayHi()
  39. less.howMany()
  40.  
  41. wanles = Person('wanles')### no problem
  42. wanles.sayHi()
  43. wanles.howMany()
  44.  
  45. ############when I uncommment any of these below
  46. ############I get the error message
  47.  
  48.  
  49.     ########     block 1     ##############
  50.  
  51. #wanless = Person('wanless')
  52. #wanless.sayHi()
  53. #wanless.howMany()
  54.  
  55.     ########     block 1     #############
  56.  
  57.  
  58.  
  59. #les = Person('les')
  60. #les.sayHi()
  61. #les.howMany()
  62.  
  63.  
  64. #wanle = Person('wanle')
  65. #wanle.sayHi()
  66. #wanle.howMany()
  67.  
  68. swaroop.sayHi()
  69. swaroop.howMany()
  70.  
Apr 21 '10 #1
9 1935
Glenton
391 Expert 256MB
What the heck?!? What's going on here? I don't get it!
Apr 22 '10 #2
woooee
43
It has to do with the __del__ function trying to print Person.population after it has been garbage collected. I do not know why this is, but perhaps has to do with reducing the counter in __del__ (as the class is destroyed) when the program exits.

Edit: If you remove the class instances yourself, then it runs correctly
Expand|Select|Wrap|Line Numbers
  1.     ## add this code at the end
  2.     ## "de-stantiate" (just kidding)
  3.     swaroop = None
  4.     less = None
  5.     wanles = None
  6.     wanless = None
  7.     les = None 
Apr 22 '10 #3
@Glenton
Thanks for answering. I was thinking as a newbie there was something I just don't know about.
Apr 22 '10 #4
@woooee
Yes it does work now. With the added code all names work. Just thought it was funny, I spent hours looking for my mistake and it was something else.
Apr 22 '10 #5
Glenton
391 Expert 256MB
What I find odd is that I can add instances like this:
Expand|Select|Wrap|Line Numbers
  1. p=[]
  2. for i in range(10):
  3.     p.append(Person('wanles'+str(i)))
and it works fine, but if you add this:
Expand|Select|Wrap|Line Numbers
  1. wanles11=p.append(Person('wanles11'))
and it breaks.

So you can have many instances and it works, provided they are packaged up in a list, but not more than 3 single instances.

Surely the garbage collection cannot be so over-zealous that it deletes itself before it's finished with the class variables?

I might even read the docs!
Apr 22 '10 #6
woooee
43
@Glenton
If you comment all lines that reference Person.population in __del__, it works also, at least as much as I have played with it.
Apr 23 '10 #7
Glenton
391 Expert 256MB
@woooee
Oh sure @woooee, I'm pretty confident that you're right that it's a case of the Person class being garbage collected, such that the class variable isn't available. But what's weird is
(1) that the class is gc before the instances are fully deleted, and
(2) that it sometimes does it and sometimes doesn't.

I just can't figure out the systematics of it. Of course __del__ is something that should be used sparingly anyway. But why?!?
Apr 23 '10 #8
If it is in garbage collection it is just not 3 names or more that sets it off.
I've tried it with Swaroop, and just one other name.
With the " = None " statements left out,
Wanless and les do not work. anless and less do work.
Also when I run the ones that do not work in Idle, the runtime errors are different from when I run it from the command line. So is that just a difference in the environments or part of the mystery?
Apr 23 '10 #9
Glenton
391 Expert 256MB
So it seems that garbage collection is an interesting and moody beast. It counts the number of references to a given object and when that reaches zero it does the garbage collection. Exactly how it does this is a bit beyond me, but it seems that when it finishes the number of references for all the variables goes to zero, and the garbage collection begins. The order of the garbage collection is not well-defined, so if you happen to delete Population before deleting all the objects, or Person before deleting the objects, then you're going to run into problems.

For this reason, errors are only raised as exceptions - that's why the code still manages to finish. There's a realisation that it doesn't really matter anymore. This is why explicitly (or implicitly) deleting the instances first makes it work.
Apr 23 '10 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

50
by: Dan Perl | last post by:
There is something with initializing mutable class attributes that I am struggling with. I'll use an example to explain: class Father: attr1=None # this is OK attr2= # this is wrong...
5
by: stephan beal | last post by:
Good afternoon, C++ers, This weekend i came across a fairly project-neutral trick which can be used to map C++ class names to their human-readable equivalents (a-la QObject's className()...
6
by: Dan Sikorsky | last post by:
If we were to define all abstract methods in an abstract class, thereby making that class non-abstract, and then override the heretofore 'abstract' methods in a derived class, wouldn't that remove...
3
by: Sven Groot | last post by:
This was posted by someone in comp.lang.c++, and later in microsoft.public.vstudio.general, but since I know Carl is in this group, and he's the one that should read this, I've reposted it here....
8
by: tshad | last post by:
I cannot seem to get the asp:textbox to use classes. Style works fine. I am trying to set the textbox to act like a label in some instance so it doesn't have a border, readonly and the background...
1
by: Chris Dunaway | last post by:
I have a legacy application that I need to build a Windows Forms application to interface with it. The legacy application keeps its configuration information in INI style files. I wish to use a...
9
by: David A. Osborn | last post by:
I have a set of classes that each have an enumeration in them, and based on dynamic input I need to access a different enumeration. For example Three classes Class_A, Class_B, and Class_C that...
6
by: n8agrin | last post by:
I've been doing some level of PHP programming for many years now, and have in the past few months started implementing lots of the core PHP5 features into a new project, when I noticed some...
49
by: Ben Voigt [C++ MVP] | last post by:
I'm trying to construct a compelling example of the need for a language feature, with full support for generics, to introduce all static members and nested classes of another type into the current...
9
by: fgh.vbn.rty | last post by:
Say I have a base class B and four derived classes d1, d2, d3, d4. I have three functions fx, fy, fz such that: fx should only be called by d1, d2 fy should only be called by d2, d3 fz should...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.