LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 800|回复: 5

python的类看不明白

[复制链接]
发表于 2005-5-20 23:55:30 | 显示全部楼层 |阅读模式
>>> class A:
...         c=1
...         def __init__(self):
...                 self.__class__.c+=1
...                
>>> A.c
1
>>> a=A()
>>> A.c,a.c
(2, 2)
>>> b=A()
>>> A.c,a.c,b.c
(3, 3, 3)

为什么三者相同呢???如果变成self.c+=1就不同,解释不通啊。
为什么三者的c是指向同一个呢?

我理解:起初类A对象的c指向1,在a=A()后应该在instance a的name space中复制一个变量c,它和A中的c指向同一个1。执行init中self.__class__.c+=1时是将A中的c重新指向新值2,而并没有影响到a中c指向的1啊,为什么a中的c也跟着变为2呢????

哪位大人帮我理解一下啊。谢谢
发表于 2005-5-21 10:36:35 | 显示全部楼层
__class__反回的就是一个实例的对象。以你自己写的代码为例,self.__class__.c == A.c。
明白不。实例在成员只能用self.member来表示,不能用self.__class__.member来表示。
所以你的代码只可能反回相同的值。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-21 10:46:51 | 显示全部楼层
楼上的你没看清吧,self.__class__.c == A.c这是肯定的我明白,实例a的成员c用a.c表示吧,这两个应该是不同的东西,为什么我改变self.__class__.c后a.c也跟着改变呢,它们成了一样的东西。

self.__class__.c是改变类对象的name space中的值,为什么实例a对象中的namespace中的c也一样改变呢。这是我不解的地方。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-21 11:21:08 | 显示全部楼层
晕死。
>>>class A:
...   a=1

A.a  ===>1     没问题
a=A()
A.a ===>1     ok
a.a ===>1     ok
A.a=2
A.a ===>2    ok
a.a ===>2    ?????就是这个我不明白啊,这两个不是在不同空间里吗,改变了A.a的值a.a也跟着改变,why???

我理解A.a和a.a象两个指针一样,在a对象产生后这两个指针都指向一个内存空间(里面存放数字1),此时A.a和a.a都是1,没错,后来A.a=2就是把A.a这个指针重新指向一个新内存空间(里面存放数字2),a.a应该还是指向存放数字1的那个内存空间,我那里理解错了,而现在的结果好像变成了A.a=2时把存放数字1的内存空间中的值从1变为2了,两个指针还指向同一个内存空间。实在不明白。那位好心人给我说说。
回复 支持 反对

使用道具 举报

发表于 2005-5-21 13:40:53 | 显示全部楼层
class test:
        a=1
>>> test.a     
1
>>> a=test()
>>> a.a
1
>>> b=test()
>>> b.a
1
>>> test.a=100    //这里的改变会影响所有的test类的实例
>>> a.a
100
>>> b.a
100
>>> a.a='a.a'   // 如果改变你的实例对象,那么类的本身改变将不会在影响你的实例对象
>>> b.a='b.a'  //同上
>>> test.a='test.a'
>>> test.a
'test.a'
>>> a.a
'a.a'
>>> b.a
'b.a'


这么解释,模块的名字空间实际是由字典实现的。一个新实例建立起来时,和类共享一个命名空间,因此类的变化会影响所有的实例。
下面看例子:
>>> class test2:
        a=2

       
>>> test2.__dict__    //内置的__dict__输出名字空间
{'a': 2, '__module__': '__main__', '__doc__': None}

>>> ta=test2()
>>> ta.a
2
>>> ta.__dict__   //新实例这时没有自己的名空间,此时他共享类的名空间
{}
>>>test.a=3
>>> test.__dict__
{'a': 3, '__module__': '__main__', '__doc__': None} //类空间里的'a'值被修改。共享的实例也会被改变
>>> ta.a
3

>>> ta.a='ta.a'  //改变你实例的值,同时实例拥有了自己的名空间,不在和类共享
>>> ta.__dict__  //名空间不在是空
{'a': 'ta.a'}

>>> test2.a='test.a'  //从类改变

>>> test2.a
'test.a'

>>> ta.a  //实例有自己的空间,不在受类的影响。
'ta.a'
>>>
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-21 21:44:18 | 显示全部楼层
谢谢楼上解释,原来不是在实例化一个类是就产生一个类空间的一个copy,而是和类空间共享
>>> class test:
...       a=1

>>>test.a   
1
>>>ta=test()
>>>test.a,ta.a
(1,1)
>>>test.a=10
>>>test.a,ta.a
(10,10)
>>>ta.a=20
>>>test.a,ta.a
(10,20)
>>>del ta.a
>>>test.a,ta.a
(10,10)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表