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 - (Initializing Swaroop)
-
Hi, my name is Swaroop.
-
I am the only person here.
-
(Initializing less)
-
Hi, my name is less.
-
We have 2 persons here.
-
(Initializing wanles)
-
Hi, my name is wanles.
-
We have 3 persons here.
-
Hi, my name is Swaroop.
-
We have 3 persons here.
-
wanles says bye.
-
There are still 2 people left.
-
less says bye.
-
There are still 1 people left.
-
Swaroop says bye.
-
I am the last one.
-
result of code with block 1 uncommented - (Initializing Swaroop)
-
Hi, my name is Swaroop.
-
I am the only person here.
-
(Initializing wanless)
-
Hi, my name is wanless.
-
We have 2 persons here.
-
(Initializing less)
-
Hi, my name is less.
-
We have 3 persons here.
-
(Initializing wanles)
-
Hi, my name is wanles.
-
We have 4 persons here.
-
Hi, my name is Swaroop.
-
We have 4 persons here.
-
wanles says bye.
-
There are still 3 people left.
-
less says bye.
-
There are still 2 people left.
-
Swaroop says bye.
-
There are still 1 people left.
-
wanless says bye.
-
Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb766f48c>> ignored
-
the code is exactly the same as the book down to line 35 - #!/usr/bin/python
-
# Filename: objvar.py
-
# Mark Wanless
-
-
class Person:
-
'''Represents a person.'''
-
population = 0
-
def __init__(self, name):
-
'''Initializes the person's data.'''
-
self.name = name
-
print '(Initializing %s)' % self.name
-
# When this person is created, he/she
-
# adds to the population
-
Person.population += 1
-
def __del__(self):
-
'''I am dying.'''
-
print '%s says bye.' % self.name
-
Person.population -= 1
-
if Person.population == 0:
-
print 'I am the last one.'
-
else:
-
print 'There are still %d people left.' % Person.population
-
def sayHi(self):
-
'''Greeting by the person.
-
Really, that's all it does.'''
-
print 'Hi, my name is %s.' % self.name
-
def howMany(self):
-
'''Prints the current population.'''
-
if Person.population == 1:
-
print 'I am the only person here.'
-
else:
-
print 'We have %d persons here.' % Person.population
-
swaroop = Person('Swaroop')
-
swaroop.sayHi()
-
swaroop.howMany()
-
-
less = Person('less') ### no problem
-
less.sayHi()
-
less.howMany()
-
-
wanles = Person('wanles')### no problem
-
wanles.sayHi()
-
wanles.howMany()
-
-
############when I uncommment any of these below
-
############I get the error message
-
-
-
######## block 1 ##############
-
-
#wanless = Person('wanless')
-
#wanless.sayHi()
-
#wanless.howMany()
-
-
######## block 1 #############
-
-
-
-
#les = Person('les')
-
#les.sayHi()
-
#les.howMany()
-
-
-
#wanle = Person('wanle')
-
#wanle.sayHi()
-
#wanle.howMany()
-
-
swaroop.sayHi()
-
swaroop.howMany()
-
9 1935
What the heck?!? What's going on here? I don't get it!
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 - ## add this code at the end
-
## "de-stantiate" (just kidding)
-
swaroop = None
-
less = None
-
wanles = None
-
wanless = None
-
les = None
@Glenton
Thanks for answering. I was thinking as a newbie there was something I just don't know about.
@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.
What I find odd is that I can add instances like this: - p=[]
-
for i in range(10):
-
p.append(Person('wanles'+str(i)))
and it works fine, but if you add this: - 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!
@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.
@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?!?
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?
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.
Sign in to post your reply or Sign up for a free account.
Similar topics
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...
|
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()...
|
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...
|
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....
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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$) {
}
...
|
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...
|
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...
|
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...
| |