python 类中 self 和 类本身变量的区别
本帖最后由 杨奇龙 于 2011-07-24 11:45 编辑当使用 self 来调用变量population的时候,此变量是属于实例的。当 Jack 构造完成,结束howmany()函数结束时Jack 实例的population 就注销了,而Tom 的population 变量还是存在的,#!/etc/bin/python
# Filename: objvar.py
class Person:
'''Represents a person.'''
population = 0
def __init__(self, name):
'''Initializes the person's data.'''
self.name = name
#!/etc/bin/python
# Filename: objvar.py
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
self.population += 1
def __del__(self):
'''I am dying.'''
print '%s is dying ' %self.name
print '%s says bye.' % self.name
self.population -= 1
if self.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 self.population == 1:
print 'I am the only person here.'
else:
print 'We have %d persons here.' % Person.population
Jack = Person('Jack')
Jack.sayHi()
Jack.howMany()
Tom = Person('Tom')
Tom.sayHi()
Tom.howMany()
print '\n Jack.population ',Jack.population
print '\n Tom.population =',Tom.population
#Jcak.sayHi()
#Jack.howMany()
"objvar.py" 56L, 1287C written
$ python objvar.py
(Initializing Jack)
Hi, my name is Jack.
I am the only person here.
(Initializing Tom)
Hi, my name is Tom.
I am the only person here.
Jack.population1
Tom.population = 1
Jack is dying
Jack says bye.
I am the last one.
Tom is dying
Tom says bye.
I am the last one.然后看看下面的帖子: 当使用 类来调用 population时,实例jack 调用完成之后,population变量随之也被注销了。Tom,Jack 不能再调用population变量了。#!/etc/bin/python
# Filename: objvar.py
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 is dying ' %self.name
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
Jack = Person('Jack')
Jack.sayHi()
Jack.howMany()
print Jack.population
Tom = Person('Tom')
Tom.sayHi()
Tom.howMany()
#Jcak.sayHi()
#Jack.howMany()
"objvar.py" 51L, 1226C written
$ python objvar.py
(Initializing Jack)
Hi, my name is Jack.
I am the only person here.
1
(Initializing Tom)
Hi, my name is Tom.
We have 2 persons here.
Jack is dying
Jack says bye.
Exception exceptions.AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0x2acbd3e31e60>> ignored
Tom is dying
Tom says bye.
Exception exceptions.AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0x2acbd3e31f38>> ignored 我想要的输出是:
(Initializing Jack)
Hi, my name is Jack.
I am the only person here.
(Initializing Tom)
Hi, my name is Tom.
We have 2 persons here.
Jack.population =2
Tom.population =2
Jack is dying
Jack says bye.
There are still 1 people left.
Tom is dying
Tom says bye.
I am the last one.
怎么编写,让jack 实例注销的时候 population的值为1 而不是 0或者 被注销 问题解决了。。很无力的原因:和源程序换了一个名称,就不行了,使用源程序是可以的
源程序地址:http://sebug.net/paper/python/ch11s06.html 回复 1# 杨奇龙
这是由于python不保证对象销毁顺序造成的。
when __del__() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the __del__() method may already have been deleted or in the process of being torn down (e.g. the import machinery shutting down). For this reason, __del__() methods should do the absolute minimum needed to maintain external invariants.
从1.5开始能够保证的仅仅是以单下划线开始的早于其他的。所以针对你的例子可以改成这样_Jack = Person('Jack')
_Jack.sayHi()
_Jack.howMany()
_Tom = Person('Tom')
_Tom.sayHi()
_Tom.howMany()
_Jack.sayHi()
_Jack.howMany()
回复 1# 杨奇龙
另外一个办法就是用self.__class__.population 代替Person.population。这样即使Person这个名字早于JackTom从当前模块删除也没问题。def __del__(self):
'''I am dying.'''
print '%s is dying ' %self.name
print '%s says bye.' % self.name
self.__class__.population -= 1
if self.__class__.population == 0
print 'I am the last one.'
else:
print 'There are still %d people left.' % self.__class__.population
......
Jack = Person('Jack')
Jack.sayHi()
Jack.howMany()
Tom = Person('Tom')
Tom.sayHi()
Tom.howMany()
Jack.sayHi()
Jack.howMany()
回复 7# 106033177
你好,这几天也遇到了这种情况,在网络上搜索了很多也没有解决一些主要的问题,有几个疑惑 1、为什么实例还没有结束,Person类就把自己的population给注销了,他是怎么判断出来用户不再使用了呢? 2、为什么 使用 self.__class__.population 就可以改变结果不在出现错误?和Person.population有什么区别呢?
页:
[1]