免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3631 | 回复: 6
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-01-28 15:54 |只看该作者 |倒序浏览
今天学习看了简明Python教程关于类的介绍,有一个Person的类的例子,我把它简化了一下,代码如下:
  1. class Person:
  2.     population = 0

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

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


  10. Tom = Person("Tom")
  11. Jim = Person("Jim")
  12.         
复制代码
在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有什么区别呢??


论坛徽章:
0
2 [报告]
发表于 2014-01-29 12:12 |只看该作者
这个问题真的很难吗?为什么看到很多人问了,但是好像都没有人能够说清楚。

论坛徽章:
0
3 [报告]
发表于 2014-01-29 12:13 |只看该作者
自己来顶一下。

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
4 [报告]
发表于 2014-01-29 13:52 |只看该作者
你研究的是Python如何管理对象的生命周期,对我这个纯Python使用者来说,比较难啊。自动内存管理(垃圾回收机制),是我用Python的重要目的之一,否则还不如用C/C++。

论坛徽章:
0
5 [报告]
发表于 2014-01-29 13:57 |只看该作者
回复 4# timespace


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

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
6 [报告]
发表于 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


   

论坛徽章:
0
7 [报告]
发表于 2014-02-01 14:50 |只看该作者
回复 6# timespace


    十分感谢,简明python里面也说到那个东西的不确定性。我又搜了一下,网上也都说是不建议使用__del__的自动回收功能,我后来又试了用del Jim 和del Tom来手动释放对象。这就没有问题了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP