python求助 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
zyAndroid
V2EX    Python

python求助

  •  
  •   zyAndroid 2011-07-09 19:00:51 +08:00 6216 次点击
    这是一个创建于 5208 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #!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
    11 条回复    1970-01-01 08:00:00 +08:00
    27493586
        1
    27493586  
       2011-07-09 20:44:54 +08:00
    python没缩进你能看懂么
    keakon
        2
    keakon  
       2011-07-09 21:43:42 +08:00
    程序结束时,析构的顺序是不一定的。你手动del wkm和del ztt就正常了。
    ayanamist
        3
    ayanamist  
       2011-07-09 21:46:18 +08:00
    同意@keakon 的观点,python除非手动del,否则__del__方法的调用时机是完全不可知的(一般情况下你不知道gc什么时候会发生),这点和Java里的Finalize方法是一样的。
    keakon
        4
    keakon  
       2011-07-09 21:46:55 +08:00
    还有一种办法就是把__del__里的Person改成self
    noGulaji
        5
    noGulaji  
       2011-07-10 08:58:44 +08:00
    @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
        6
    keakon  
       2011-07-10 09:51:05 +08:00
    那就没办法了,因为在析构对象前,Person类及其成员已经被析构了。
    reus
        7
    reus  
       2011-07-10 11:56:15 +08:00
    试了下,可以用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
        8
    reus  
       2011-07-10 11:58:37 +08:00
    哦,我用的是2.7……2.5不清楚有没有差异
    Hyperion
        9
    Hyperion  
       2011-07-10 12:46:42 +08:00
    =_= 在邮件列表里看到过...

    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
        10
    zyAndroid  
    OP
       2011-07-10 13:10:12 +08:00
    @27493586 @Hyperion @reus @keakon @keakon 感谢各位的解答!
    noGulaji
        11
    noGulaji  
       2011-07-11 11:07:22 +08:00
    @reus 确实不错,__class__ 是每个类实例的一个内置属性 (也是每个类的)。它是一个类的引用,而 self 是一个类 (在本例中,是 Person 类) 的实例。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2715 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 09:03 PVG 17:03 LAX 02:03 JFK 05:03
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86