python求助

2011 年 7 月 9 日
 zyAndroid
#!usr/bin/python

class Person:
population = 0

def __init__(self,name):
self.name=name
print 'Initializing %s' % self.name
Person.population += 1

def __del__(self):
Person.population -= 1

if Person.population == 0:
print 'I am the last one.'
else:
print "There are still %d people left." %Person.population
print '%s says bye.' % self.name
wkm = Person("wang")
ztt = Person("ztt") #第20行

程序执行结果:
Initializing wang
Initializing ztt
There are still 1 people left.
wang says bye.
Exception exceptions.AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0x7f6eac025368>> ignored

但是如果将第20行的对象ztt改名之后,也不一定好使,比如,改成zhaoyu之后程序正常运行,
执行结果如下:
Initializing wang
Initializing zhaoyu
There are still 1 people left.
zhaoyu says bye.
I am the last one.
wang says bye.
但如果改成z之后,执行结果就又跟ztt的时候一样了。

也就是说这段程序,出错还是不出错 跟对象名有关,这是为什么呢?

python版本:Python 2.5.2
系统信息:Ubuntu 10.04
6572 次点击
所在节点    Python
11 条回复
27493586
2011 年 7 月 9 日
python没缩进你能看懂么
keakon
2011 年 7 月 9 日
程序结束时,析构的顺序是不一定的。你手动del wkm和del ztt就正常了。
ayanamist
2011 年 7 月 9 日
同意@keakon 的观点,python除非手动del,否则__del__方法的调用时机是完全不可知的(一般情况下你不知道gc什么时候会发生),这点和Java里的Finalize方法是一样的。
keakon
2011 年 7 月 9 日
还有一种办法就是把__del__里的Person改成self
noGulaji
2011 年 7 月 10 日
@keakon 如果把__del__里的Person改成self后,self.population的值只加不减了,如下结果:Initializing wang
Initializing ztt
There are still 1 people left.
wang says bye.
There are still 1 people left.
ztt says bye.
keakon
2011 年 7 月 10 日
那就没办法了,因为在析构对象前,Person类及其成员已经被析构了。
reus
2011 年 7 月 10 日
试了下,可以用self.__class__.population,运行正常
因为文档没有提到这点(或者我没找到),所以根据现象猜测下
Person类没有析构,因为还有对象的属性强reference到它,而只是Person这个name不再reference到该类对象(所以只是减少了reference count,没有到析构条件
可以验证一下
先import sys
然后在__init__里面加入:self.getrefcount = sys.getrefcount
加入这句是保证在对象析构之前,这个函数都能用(因为可能在对象调用__del__之前,sys模块就被卸掉了
然后在__del__里面:print self.getrefcount(self.__class__)
可以看到第一次__del__时,输出5,第二次输出3,所以类是还没有析构的(refcount未到0),只是用Person这个name得不到而已
reus
2011 年 7 月 10 日
哦,我用的是2.7……2.5不清楚有没有差异
Hyperion
2011 年 7 月 10 日
=_= 在邮件列表里看到过...

Class and Object Variables
(http://www.ibiblio.org/g2swap/byteofpython/read/class-and-object-vars.html)

相关讨论楼:
python程序的最后关头,是怎么样的呢?
(http://groups.google.com/group/python-cn/browse_thread/thread/31df4e6076782599/)
zyAndroid
2011 年 7 月 10 日
@27493586 @Hyperion @reus @keakon @keakon 感谢各位的解答!
noGulaji
2011 年 7 月 11 日
@reus 确实不错,__class__ 是每个类实例的一个内置属性 (也是每个类的)。它是一个类的引用,而 self 是一个类 (在本例中,是 Person 类) 的实例。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/15550

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX