杨奇龙 发表于 2011-07-24 11:41

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.然后看看下面的帖子:

杨奇龙 发表于 2011-07-24 11:45

当使用 类来调用 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

杨奇龙 发表于 2011-07-24 11:48

我想要的输出是:
(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.

杨奇龙 发表于 2011-07-24 11:49

怎么编写,让jack 实例注销的时候 population的值为1 而不是 0或者 被注销

杨奇龙 发表于 2011-07-24 13:54

问题解决了。。很无力的原因:和源程序换了一个名称,就不行了,使用源程序是可以的
源程序地址:http://sebug.net/paper/python/ch11s06.html

106033177 发表于 2011-07-25 09:22

回复 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()

106033177 发表于 2011-07-25 09:38

回复 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()

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

回复 7# 106033177


    你好,这几天也遇到了这种情况,在网络上搜索了很多也没有解决一些主要的问题,有几个疑惑 1、为什么实例还没有结束,Person类就把自己的population给注销了,他是怎么判断出来用户不再使用了呢? 2、为什么 使用 self.__class__.population 就可以改变结果不在出现错误?和Person.population有什么区别呢?
页: [1]
查看完整版本: python 类中 self 和 类本身变量的区别