python中定义类的问题

delphiwcdj 2010-07-14 02:44:39
问题是为什么第一次执行和以后执行的结果不同呢?
代码如下:

class Person:
'''Represents a person.'''
population=0
def __init__(self,name):
'''Initializes the person's data.'''
self.name=name
print '(Initializing %s)' % self.name
# When this person is created, he/she
# adds to the population
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

gerry=Person('Gerry Young')
gerry.sayHi()
gerry.howMany()

输入如下:

>>>
(Initializing Gerry Young)
Hi, my name is Gerry Young.
I am the only person here.
>>>
(Initializing Gerry Young)
Gerry Young says bye.
I am the last one.
Hi, my name is Gerry Young.
We have 0 persons here.
>>>

实际问题就是__del__的调用执行问题,在对象不用的时候,将调用此方法,但是具体什么时候调用,在看书的时候解释地不是很清楚。希望大牛可以帮忙解释一下。就上面这个代码的输出结果有些疑惑,和C++的对象相比好像大有不同。谢谢!
...全文
379 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
angel_su 2010-07-15
  • 打赏
  • 举报
回复
前面我说直接运行意思是在命令窗口下python.exe 脚本文件名.py这样退出python前会自动调用__del__:
(Initializing Gerry Young)
Hi, my name is Gerry Young.
I am the only person here.
Gerry Young says bye.
I am the last one.

交互下第一次执行到代码最后时python并未退出,gerry还存在着原对象所以不会调用__del__。第二次gerry换成新一个对象,原对象这时才会被删掉,不过你看__del__输出是在第二次init后而不是前...。如果你习惯在交互模式下测试,测试那部分代码最好写成函数形式,也就是gerry在函数里,不在global下...
def main():
gerry=Person('Gerry Young')
gerry.sayHi()
gerry.howMany()

if __name__ == '__main__':
main()
delphiwcdj 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 z4none 的回复:]

"对象不用的时候" 用C++来看应该类似于 "对象没有被引用的时候" 或者 "没有被指向的时候"

Python code

>>> man = Person('Jacob') # Person('Jacob') 被 man 引用
(Initializing Jacob)
>>> man = Person('Jack') # man 变成别的了, Person('Jacob') 不被需要了……
[/Quote]
谢谢,问题是在当作整个脚本执行的时候,并没有输出__del__中的内容,在交互的时候却可以。
delphiwcdj 2010-07-15
  • 打赏
  • 举报
回复
@angel_su
恩,谢谢。希望您能推荐本不错的教材
劲草 2010-07-15
  • 打赏
  • 举报
回复
3楼正解
angel_su 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 delphiwcdj 的回复:]

在命令提示符下运行下面这个脚本,即 python test.py,提示有错。
Exception exceptions.AttributeError:"'NoneType' object has no attribute 'population'"in <bound method Person.__del__ of <__main__.Person instance at 0x00A455D0……
[/Quote]
我觉得是个bug,不久前有人提过相同问题。看看:
http://topic.csdn.net/u/20100617/00/55e2d94b-1dc7-40ee-ad15-18cef7fba89b.html

改进的办法如上说过弄进一个函数里:
def main():
gerry=Person('Gerry Young')
gerry.sayHi()
gerry.howMany()
w=Person('wcdj')
w.sayHi()
w.howMany()

if __name__ == "__main__":
main()

又或者用try...except忽略它:
try:
Person.population -= 1
if Person.population==0:
print 'I am the last one.'
else:
print 'there are still %d people left.' % Person.population
except:
pass

又或者干脆不管了,因为错误发生是在代码执全部行完毕准备退出python时...
idoubtit 2010-07-15
  • 打赏
  • 举报
回复
up!
delphiwcdj 2010-07-15
  • 打赏
  • 举报
回复
7L说错了,我理解了,就是根据对象的生命周期(局部的和global的),如果到了就调用__del__方法。通过python XXX.py的方式是可以看到__del__方法输出的。
delphiwcdj 2010-07-15
  • 打赏
  • 举报
回复
在命令提示符下运行下面这个脚本,即 python test.py,提示有错。
Exception exceptions.AttributeError:"'NoneType' object has no attribute 'population'"in <bound method Person.__del__ of <__main__.Person instance at 0x00A455D0>> ignored

请问这个是什么错误呢?谢谢

class Person:
'''Represents a person.'''
population=0
def __init__(self,name):
'''Initializes the person's data.'''
self.name=name
print '(Initializing %s)' % self.name
# When this person is created, he/she
# adds to the population
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


gerry=Person('Gerry Young')
gerry.sayHi()
gerry.howMany()

w=Person('wcdj')
w.sayHi()
w.howMany()
delphiwcdj 2010-07-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 angel_su 的回复:]

前面我说直接运行意思是在命令窗口下python.exe 脚本文件名.py这样退出python前会自动调用__del__:
[/Quote]
也就是说通过运行脚本文件的方式,是看不到__del__中的输出的。我刚开始学疑问比较多,谢谢你的回答。
PS: 怎么在IDLE下显示行号呢?在网上没有找到解决方法。
z4none 2010-07-15
  • 打赏
  • 举报
回复
"对象不用的时候" 用C++来看应该类似于 "对象没有被引用的时候" 或者 "没有被指向的时候"


>>> man = Person('Jacob') # Person('Jacob') 被 man 引用
(Initializing Jacob)
>>> man = Person('Jack') # man 变成别的了, Person('Jacob') 不被需要了
(Initializing Jack)
Jacob says bye.
there are still 1 people left.
>>> man.population
1
>>>
delphiwcdj 2010-07-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 angel_su 的回复:]

直接运行脚本试试,应该会符合预期吧,交互模式下变量gerry计数不会自动归0,要主动del的样子...
[/Quote]
试了一下是这样的。还有个问题是__del__方法为什么没有执行?为什么没有输出。
angel_su 2010-07-14
  • 打赏
  • 举报
回复
直接运行脚本试试,应该会符合预期吧,交互模式下变量gerry计数不会自动归0,要主动del的样子...

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧