class Person:
'''Represents a person.'''
population = 0
def __init__(self,name):
'''Initializes the person's data.'''
self.name = name
print '(Initializing %s)' % self.name
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
jerry = Person('Jerry')
jerry.sayHi()
jerry.howMany()
qiu = Person('Qiu')
qiu.sayHi()
qiu.howMany()
jerry.sayHi()
jerry.howMany()
出现如下错误:
Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0x01AF97D8>> ignored
原因如下:
At interpreter shutdown, the module's global variables are set to None before the module itself is released.
__del__ methods may be called in those precaries circumstances, and should not rely on any global state.
将__del__方法中对类变量的访问方式改为如下即可:
def __del__(self):
self.__class__.population -= 1
Hello 1
World 2
aaaa 3
Over
DeException l Hello 2
AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF18D0>> ignored
Exception AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF1970>> ignored
Hello 1
World 2
aaaa 3
Over
Del Hello 2
Del World 1
Del aaaa 0
Perfect!我们完美地处理了这个问题!
PS:
书上又提到了一些问题,在这里作补充(仅作为参考):
__new__()是唯一在实例创建之前执行的方法,一般用在定义元类时使用。
del xxx 不会主动调用__del__方法,只有引用计数==0时,__del__()才会被执行,并且定义了__del_()的实例无法被Python的循环垃圾收集器收集,所以尽量不要自定义__del__()。一般情况下,__del__() 不会破坏垃圾处理器。