免费注册 查看新帖 |

Chinaunix

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

python 类中 self 和 类本身变量的区别 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-07-24 11:41 |只看该作者 |倒序浏览
本帖最后由 杨奇龙 于 2011-07-24 11:45 编辑

当使用 self 来调用变量population的时候,此变量是属于实例的。当 Jack 构造完成,结束howmany()函数结束时Jack 实例的population 就注销了,而Tom 的population 变量还是存在的,
  1. #!/etc/bin/python
  2. # Filename: objvar.py

  3. class Person:
  4.     '''Represents a person.'''
  5.     population = 0

  6.     def __init__(self, name):
  7.         '''Initializes the person's data.'''
  8.         self.name = name
  9. #!/etc/bin/python
  10. # Filename: objvar.py

  11. class Person:
  12.     '''Represents a person.'''
  13.     population = 0

  14.     def __init__(self, name):
  15.         '''Initializes the person's data.'''
  16.         self.name = name
  17.         print '(Initializing %s)' % self.name

  18.         # When this person is created, he/she
  19.         # adds to the population
  20.       [b]  self.population += 1[/b]

  21.     def __del__(self):
  22.         '''I am dying.'''
  23.         print '%s is dying ' %self.name
  24.         print '%s says bye.' % self.name

  25.         [b]self.population -= 1[/b]


  26.         if self.population == 0:
  27.             print 'I am the last one.'
  28.         else:
  29.             print 'There are still %d people left.' % Person.population

  30.     def sayHi(self):
  31.         '''Greeting by the person.

  32.         Really, that's all it does.'''
  33.         print 'Hi, my name is %s.' % self.name

  34.     def howMany(self):
  35.         '''Prints the current population.'''
  36.         if self.population == 1:
  37.             print 'I am the only person here.'
  38.         else:
  39.             print 'We have %d persons here.' % Person.population

  40. Jack = Person('Jack')
  41. Jack.sayHi()
  42. Jack.howMany()


  43. Tom = Person('Tom')
  44. Tom.sayHi()
  45. Tom.howMany()
  46. print '\n Jack.population ',Jack.population
  47. print '\n Tom.population =',Tom.population


  48. #Jcak.sayHi()
  49. #Jack.howMany()
  50. "objvar.py" 56L, 1287C written
  51. [yang@rac1 python]$ python objvar.py
  52. (Initializing Jack)
  53. Hi, my name is Jack.
  54. I am the only person here.
  55. (Initializing Tom)
  56. Hi, my name is Tom.
  57. I am the only person here.

  58. Jack.population  1

  59. Tom.population = 1
  60. Jack is dying
  61. Jack says bye.
  62. I am the last one.
  63. Tom is dying
  64. Tom says bye.
  65. I am the last one.
复制代码
然后看看下面的帖子:

论坛徽章:
0
2 [报告]
发表于 2011-07-24 11:45 |只看该作者
当使用 类来调用 population时,实例jack 调用完成之后,population变量随之也被注销了。Tom,Jack 不能再调用population变量了。
  1. #!/etc/bin/python
  2. # Filename: objvar.py

  3. class Person:
  4.     '''Represents a person.'''
  5.     population = 0

  6.     def __init__(self, name):
  7.         '''Initializes the person's data.'''
  8.         self.name = name
  9.         print '(Initializing %s)' % self.name

  10.         # When this person is created, he/she
  11.         # adds to the population
  12.        [b] Person.population += 1[/b]

  13.     def __del__(self):
  14.         '''I am dying.'''
  15.         print '%s is dying ' %self.name
  16.         print '%s says bye.' % self.name

  17.        [b] Person.population -= 1[/b]


  18.         if Person.population == 0:
  19.             print 'I am the last one.'
  20.         else:
  21.             print 'There are still %d people left.' % Person.population

  22.     def sayHi(self):
  23.         '''Greeting by the person.

  24.         Really, that's all it does.'''
  25.         print 'Hi, my name is %s.' % self.name

  26.     def howMany(self):
  27.         '''Prints the current population.'''
  28.         if Person.population == 1:
  29.             print 'I am the only person here.'
  30.         else:
  31.             print 'We have %d persons here.' % Person.population

  32. Jack = Person('Jack')
  33. Jack.sayHi()
  34. Jack.howMany()
  35. print Jack.population
  36. Tom = Person('Tom')
  37. Tom.sayHi()
  38. Tom.howMany()
  39. #Jcak.sayHi()
  40. #Jack.howMany()
  41. "objvar.py" 51L, 1226C written                                                                                                                       
  42. [yang@rac1 python]$ python objvar.py
  43. (Initializing Jack)
  44. Hi, my name is Jack.
  45. I am the only person here.
  46. 1
  47. (Initializing Tom)
  48. Hi, my name is Tom.
  49. We have 2 persons here.
  50. Jack is dying
  51. Jack says bye.        
  52. Exception exceptions.AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0x2acbd3e31e60>> ignored
  53. Tom is dying
  54. Tom says bye.
  55. Exception exceptions.AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0x2acbd3e31f38>> ignored
复制代码

论坛徽章:
0
3 [报告]
发表于 2011-07-24 11:48 |只看该作者
我想要的输出是:

  1. (Initializing Jack)
  2. Hi, my name is Jack.
  3. I am the only person here.
  4. (Initializing Tom)
  5. Hi, my name is Tom.
  6. We have 2 persons here.
  7. Jack.population =2
  8. Tom.population =2
  9. Jack is dying
  10. Jack says bye.
  11. There are still 1 people left.
  12. Tom is dying
  13. Tom says bye.
  14. I am the last one.
复制代码

论坛徽章:
0
4 [报告]
发表于 2011-07-24 11:49 |只看该作者
怎么编写,让jack 实例注销的时候 population的值为1 而不是 0或者 被注销

论坛徽章:
0
5 [报告]
发表于 2011-07-24 13:54 |只看该作者
问题解决了。。很无力的原因:和源程序换了一个名称,就不行了,使用源程序是可以的
源程序地址:http://sebug.net/paper/python/ch11s06.html

论坛徽章:
0
6 [报告]
发表于 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开始能够保证的仅仅是以单下划线开始的早于其他的。所以针对你的例子可以改成这样
  1. _Jack = Person('Jack')
  2. _Jack.sayHi()
  3. _Jack.howMany()

  4. _Tom = Person('Tom')
  5. _Tom.sayHi()
  6. _Tom.howMany()
  7. _Jack.sayHi()
  8. _Jack.howMany()
复制代码

论坛徽章:
0
7 [报告]
发表于 2011-07-25 09:38 |只看该作者
回复 1# 杨奇龙

另外一个办法就是用self.__class__.population 代替Person.population。这样即使Person这个名字早于Jack  Tom从当前模块删除也没问题。
  1.   def __del__(self):
  2.         '''I am dying.'''
  3.         print '%s is dying ' %self.name
  4.         print '%s says bye.' % self.name
  5.         self.__class__.population -= 1
  6.         if self.__class__.population == 0
  7.             print 'I am the last one.'
  8.         else:
  9.             print 'There are still %d people left.' % self.__class__.population

  10. ......

  11. Jack = Person('Jack')
  12. Jack.sayHi()
  13. Jack.howMany()

  14. Tom = Person('Tom')
  15. Tom.sayHi()
  16. Tom.howMany()
  17. Jack.sayHi()
  18. Jack.howMany()
复制代码

论坛徽章:
0
8 [报告]
发表于 2014-01-29 13:52 |只看该作者
回复 7# 106033177


    你好,这几天也遇到了这种情况,在网络上搜索了很多也没有解决一些主要的问题,有几个疑惑 1、为什么实例还没有结束,Person类就把自己的population给注销了,他是怎么判断出来用户不再使用了呢? 2、为什么 使用 self.__class__.population 就可以改变结果不在出现错误?和Person.population有什么区别呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP