Python:类与对象的变量[SimpleClass.py]

来源:互联网 发布:女生一个人旅行 知乎 编辑:程序博客网 时间:2024/05/16 12:11

【异常分析】

Exception AttributeError: "'NoneType' object has no attribute 'Population'" in <bound method__del__ of <__main__.Person instance at0x00BC4D50>> ignored

在理解“类与对象的变量”时编写了下面一段程序:

#coding=utf-8#类与对象的变量#类的变量和对象的变量,与类和对象的名称空间绑定,即变量的名称只在这些类和对象的前提下有效。#类的变量和对象的变量,根据是类还是对象拥有变量而区分:#1)类的变量:类的所有对象共享使用。#2)对象的变量:类的每个对象拥有,每个对象有自己对这个域的一份拷贝。import gc#1. 定义一个类class Person:    '''RePresents a person'''    Population = 0    #2.对象的方法#__init__方法:在类的一个对象被创建时运行,用来给对象做一些期望的初始化    def __init__(self, name):'''Initializes the person's data.'''self.name = nameprint 'Initiallizing %s' % self.name        Person.Population += 1            def __del__(self):        print '\n%s says bye.'% self.name        #print '\'Person\' = ', globals()['Person']        #print globals().keys()                Person.Population -= 1        #self.__class__.Population -= 1                if Person.Population == 0:            print 'I am the last person.'        else:            print 'There are still %d person left.'% Person.Population    def sayHi(self):    #函数定义时必须提供参数self,调用sayHi()方法时没有任何参数'''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 'There are %d persons here.'% Person.Populationgc.set_debug(gc.DEBUG_STATS | gc.DEBUG_LEAK)#创建一个对象swaroop = Person('swaroop') #此时创建对象如果不提供入参,将提示错误:#TypeError: __init__() takes exactly 2 arguments (1 given) #使用对象的方法swaroop.sayHi() swaroop.howMany()kalam = Person('kalam')kalam.sayHi()kalam.howMany()#以上代码的运行时没有问题的,但添加以下代码后,运行出现了问题Tom = Person('Tom') Tom.sayHi() Tom.howMany()Jerry = Person('Jerry')Jerry.sayHi()Jerry.howMany()

#运行结果:

Initiallizing swaroop
Hi, my name is swaroop
I am the only person here.
Initiallizing kalam
Hi, my name is kalam
There are 2 persons here.
Initiallizing Tom
Hi, my name is Tom
There are 3 persons here.
Initiallizing Jerry
Hi, my name is Jerry
There are 4 persons here.
gc: collecting generation 2...
gc: objects in each generation: 431 3336 0
gc: done, 0.0000s elapsed.

kalam says bye.
There are still 3 person left.

Jerry says bye.
There are still 2 person left.

swaroop says bye.
There are still 1 person left.

Tom says bye.
Exception AttributeError: "'NoneType' object has no attribute 'Population'" in <bound method Person.

__del__ of <__main__.Person instance at 0x00BC7648>> ignored


在打印Tom says bye.之后,提示错误:
Exception AttributeError: "'NoneType' object has no attribute 'Population'" in <bound method Person.__del__ of <__main__.Person instance at 0x00BC4CB0>> ignored

出现问题的原因,简单的说,就是python的垃圾回收机制不保证对象的销毁顺序。
Person这个引用变成None了,但是它之前指向的那个对象还在(也就是用self.__class__代替Person访问population没有问题)

在Python中不能将释放紧迫资源的机会依赖于__del__函数,最好是手动释放。

从Python的垃圾回收机制上给出的一些解析

问题的分析过程:
https://groups.google.com/forum/#!topic/python-cn/AYOlxnj-_BY
http://bbs.csdn.net/topics/340133602
http://linluxiang.iteye.com/blog/746224