lovekaiyuan 发表于 2014-01-28 15:54

简明Python教程中关于一个Person类的问题。(好像涉及Python的回收机制)

今天学习看了简明Python教程关于类的介绍,有一个Person的类的例子,我把它简化了一下,代码如下:class Person:
    population = 0

    def __init__(self, name):
      self.name = name
      print("Initialising a person:%s" %self.name)
      Person.population += 1

    def __del__(self):
      print("%s is dead." %self.name)
      Person.population -= 1


Tom = Person("Tom")
Jim = Person("Jim")
      
在windows的cmd中执行的时候,如果执行的次数多了以后就会出现如下的错误:
Initialising a person:Tom
Initialising a person:Jim
Jim is dead.
Exception AttributeError: "'NoneType' object has no attribute 'population'" in <
bound method Person.__del__ of <__main__.Person object at 0x00C2B9F0>> ignored
Tom is dead.
Exception AttributeError: "'NoneType' object has no attribute 'population'" in <
bound method Person.__del__ of <__main__.Person object at 0x00B5DAD0>> ignored

在网上找了很多,解决方法也比较简单,把Person.population 换成 self.__class__.population即可,出现的原因是因为垃圾回收机制,
我想问一下,是什么样的垃圾回收机制导致这种情况的出现??
为什么使用self.__class__.population就可以解决,他和Person.population有什么区别呢??


lovekaiyuan 发表于 2014-01-29 12:12

这个问题真的很难吗?为什么看到很多人问了,但是好像都没有人能够说清楚。

lovekaiyuan 发表于 2014-01-29 12:13

自己来顶一下。

timespace 发表于 2014-01-29 13:52

你研究的是Python如何管理对象的生命周期,对我这个纯Python使用者来说,比较难啊。自动内存管理(垃圾回收机制),是我用Python的重要目的之一,否则还不如用C/C++。

lovekaiyuan 发表于 2014-01-29 13:57

回复 4# timespace


    我也是刚开始学习的,我记得第一次按照例子来敲代码并执行的时候并没有出现错误,可能正好碰到了按照正常的顺序注销,可是昨天又敲了一遍执行的时候发现出现了问题,不知道为什么google一下发现很多都问过,不过没有说的太清楚的只是说了解决的方法,用 self.__class__.population来代替。问一下,self.__class__.population和Person.population有什么区别呢?

timespace 发表于 2014-01-29 14:59

回复 5# lovekaiyuan
关于self.__class__.population和Person.population。在我看来,在对象生命周期内,这两个用法还真没区别。
但问题的复杂之处在于你引入了__del__,这个方法有不确定性,文档就对这个方法做了Note和Warning,也就是说__del__调用时,其内部引用的对象有可能已被回收。
例如,Person是class object, Jim和Tom都是class instance object,Jim或Tom的__del__调用时,你是直接引用Person这个对象,此时Person可能被回收,但self.__class__会隐式创建一个从class instance object指向class object闭包引用,就是说只要Jim或Tom在,Person就至少有一个引用计数而不会被回收,保证了执行的正确性。上述推理是看官方文档猜的,很可能是无稽之谈。
参考:The Python Language Reference -> 3. Data model -> 3.3. Special method names -> 3.3.1. Basic customization & 3.3.3. Customizing class creation


   

lovekaiyuan 发表于 2014-02-01 14:50

回复 6# timespace


    十分感谢,简明python里面也说到那个东西的不确定性。我又搜了一下,网上也都说是不建议使用__del__的自动回收功能,我后来又试了用del Jim 和del Tom来手动释放对象。这就没有问题了。
页: [1]
查看完整版本: 简明Python教程中关于一个Person类的问题。(好像涉及Python的回收机制)