1、问题背景
当使用Python类时,可以使用构造函数和析构函数来初始化和清理类实例。构造函数在创建类实例时自动调用,而析构函数在删除类实例时自动调用。
在上面的代码示例中,Person类具有一个构造函数__init__和一个析构函数__del__。构造函数__init__在Person类的实例被创建时被调用,它将类实例的name属性设置为传入的参数,并将类实例的人口计数population加1。析构函数__del__在Person类的实例被删除时被调用,它将类实例的人口计数population减1。
问题是,如果我在程序中显式地删除Person类的实例,析构函数__del__是否会被自动调用,或者我是否需要在“main”程序/类中添加一些东西,如上面的代码示例所示?
2、解决方案
析构函数__del__会在垃圾回收器收集对象时自动调用,而不是在丢失对对象的最后一个引用时,也不是在执行del object时调用。del__负责调用超类中的任何__del,尽管目前尚不清楚这是按照方法解析顺序(MRO)还是仅仅调用每个超类。具有__del__意味着垃圾回收器放弃检测和清理任何循环链接,例如丢失对链表的最后一个引用。您可以从gc.garbage中获取被忽略的对象列表。您有时可以使用弱引用来完全避免循环。
del__函数可以作弊,保存对对象的引用,并停止垃圾回收。在__del__中显式引发的异常会被忽略。del__更类似于__new,而非__init,这可能会令人困惑。
del__在Python中并不是一个“受宠”的孩子。您会注意到sys.exit()文档没有指定在退出之前是否收集垃圾,并且有很多奇特的问题。对全局变量调用__del__会导致奇怪的排序问题,例如http://bugs.python.org/issue5099。即使__init__失败,是否也应该调用__del?有关详细信息,请参阅http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423。
代码示例:
class Person:'''Represents a person '''population = 0def __init__(self,name):# some statements and population += 1def __del__(self):# some statements and population -= 1 def sayHi(self):'''grettings from person'''print 'Hi My name is %s' % self.namedef howMany(self):'''Prints the current population'''if Person.population == 1:print 'i am the only one here'else:print 'There are still %d guyz left ' % Person.population
rohan = Person('Rohan')
rohan.sayHi()
rohan.howMany()sanju = Person('Sanjivi')
sanju.howMany()del rohan # am i doing this correctly?
输出:
Initializing person data******************************************Initializing Rohan******************************************Population now is: 1Hi My name is Rohani am the only one hereInitializing person data******************************************Initializing Sanjivi******************************************Population now is: 2In case Person dies:******************************************Sanjivi Bye Bye worldthere are still 1 people lefti am the only one hereIn case Person dies:******************************************Rohan Bye Bye worldi am the last person on earthPopulation now is: 0