请教Python中的变量定义

请教Python中的变量定义

初学Python,写了个简单的程序,老是有问题

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/python
# Filename: class.py

class Person:
        '''Defination of class Person'''
        count=0        
       
        def __init__(self,name):
                '''defination of constructor'''
                self.name = name
                Person.count+=1
                print self.name,'is created'

        def __del__(self):
                '''defination of destructor.'''
                print 'says bye to %s' %self.name

                Person.count-=1               
                if Person.count==0:
                        print self.name,'is the last one.'
                       
        def howmuch(self):
                return Person.count
                       
        def sayhello(self):
                print 'hello,',self.name       

p = Person('edward')

运行结果

[Copy to clipboard] [ - ]
CODE:
edward is created
says bye to edward
Exception exceptions.AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Person.__del__ of <__main__.Person instance at 0xb7e96c4c>> ignored

找了半天原因,原来问题出在这里

[Copy to clipboard] [ - ]
CODE:
p = Person('edward')

改成

[Copy to clipboard] [ - ]
CODE:
pedward = Person('edward')

以后,问题解决了.
但是却不知道到底是为什么.难道python中不允许用比较短的变量名吗,有人知道原因不,请告诉一声,谢谢了.
应该不是变量的问题。
看提示好像是你计数器的问题。
不用Person.count,改用self.count应该更好吧。

PS:你的程序我运行没有问题。
可能是我们用的python的版本不一样,而我用的版本有bug吧
把  count=0      
改成 self. count=0
这里有说明:
http://docs.python.org/ref/customization.html#l2h-175

在模块销毁时, 此时发生的__del__调用, 有可能引用到的全局对象已经不存在了, 所以会有异常。但这有可能是不确定的。

解决的办法:

1 在模块销毁之前, 先销毁对象, 即在程序结束前, 加一句:

p = Person("edward")

# other actions

p = None

2 另有一种办法。按照python的规则, 下划线命名的对象先于其他对象销毁, 所以, 可以在给类的实例命名时加一个下划线前缀:

_p = Person("edward")

国外论坛上有一个类似的例子, 顺着查了查python的在线文档, 真是处处有陷阱啊。

这个错误是由于对象销毁的顺序造成的。即Person类先销毁,其后实例p销毁的时候找不到Person类故出错。
但是,另一个问题是为什么变量名用p的时候是Person类先销毁,而用pedward的时候确是实例先销毁呢?如果说是偶然,为什么在不同的机器上都是这样呢?如果说是必然,又有什么根据呢?难道变量的名字真的能影响到其在命名空间中的顺序?
stone.zh和jkit说得很有道理,将变量名称改成以下划线开头或者先手动销毁对象都可以解决这个问题,原文如下

QUOTE:
Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted;

严格地说,这应该是Python的一个bug,为什么会出现这个问题了,我觉得一般来说,一个语言的符号表都是Hash 表,没有什么可说的,变量在其中的顺序肯定是和变量的名字有关的.在销毁这些对象的时候Python可能患了个愚蠢的错误,那就是依次按照顺序去销毁这些对象,显然这样是不合理的.对象的销毁顺序应该是有优先级的.肯定要先局部后全局.

看来 Python 有必要引入“引用记数”一类的技术。
什么意思?python就是这样的处理的呀。当del一个对象时并不是直接释放,而是对这个对象的引用计数减1。为0时释放。


QUOTE:
原帖由 limodou 于 2006-6-10 13:39 发表
什么意思?python就是这样的处理的呀。当del一个对象时并不是直接释放,而是对这个对象的引用计数减1。为0时释放。

是吗?
我不太清楚 Python 的实现,
不过楼主碰到的问题,
如果 Person 的释放是引用数减一的话,那么 p 还没有释放值钱,Person 就不应该真正释放,
那么前面的几位朋友所说的情况(因为 Person 销毁了,因此 p 销毁时出问题)应该就不对了哦。