关于 python(3) 类属性和数据属性的问题, 为什么 可以用 self.cls_attr 作为右值,作为左值却会覆盖为 数据属性?

2015-08-07 13:23:49 +08:00
 raiz
class A():
    cls_attr = 1

    def fun1(self):
        print(self.cls_attr)

    def fun2(self):
        self.cls_attr += 1

a = A()

print(a.cls_attr)    # 1

fun1()              # 1

fun2()

print(a.cls_attr)    # 1

fun1()           #2
2336 次点击
所在节点    Python
10 条回复
caoyue
2015-08-07 16:50:23 +08:00
我的理解是 在实例空间中找不到 cls_attr 也会去类空间中找
所以 print(a.cls_attr) 是 1
然后 self.cls_attr += 1 在实例空间中创造了 cls_attr
所以 print(a.cls_attr) 是 2 (楼主这里写错了?)
如果你看 A.cls_attr,应该还是 1
Cynic222
2015-08-07 17:02:15 +08:00
你确定你的代码你跑过?
imlonghao
2015-08-07 17:18:48 +08:00
你下面调用的时候
哪里来的 fun1 ?
哪里来的 fun2 ?
raiz
2015-08-07 18:21:46 +08:00
@imlonghao
@Cynic222 不好意思 代码实在这里现码的, 打错, 都是 通过 a.funN() 调用
@caoyue
对 a.cls_attr 是2 我本来想打的是 A.cls_attr 是1

下面是在 consola 中打的
```
>>> class A():
... cls_attr = 1
... def fun1(self):
... print(self.cls_attr)
... def fun2(self):
... self.cls_attr += 1
...
>>> a = A()
>>> a.cls_attr
1
>>> a.fun1()
1
>>> a.fun2()
>>> a.cls_attr
2
>>> A.cls_attr
1
>>> a.fun1()
2
```
zealot0630
2015-08-07 18:24:59 +08:00
楼主看一下A.__dict__和a.__dict__就明白了
raiz
2015-08-07 18:25:06 +08:00
@caoyue self.cls_attr += 1 不应该意识 “赋值给为声明的变量“吗 或者 直接访问 类属性吗
raiz
2015-08-07 18:37:56 +08:00
@zealot0630 嗯 我看到了类和实例的字典里都有 cls_attr 这个变量, 实例的是在 调用 fun2() 之后生成的, 我问题就在于为什么 读 self.cls_attr 的时候能访问到 类属性,而不会提示找不到, 而赋值的时候又会去生成一个实例变量

>>> a.__dict__
{'cls_attr': 2}
>>> A.__dict__
{'__module__': '__main__', '__doc__': None, 'fun1': <function fun1 at 0x00000000025CA5F8>, 'cls_attr': 1, 'fun2': <function fun2 at 0x00>}
caoyue
2015-08-07 19:22:09 +08:00
@raiz
如果这里是
v = self.cls_attr + 1
self.cls_attr = v
是不是好理解点……

可以看看 Python 的 namespace 和 scope rules 相关的内容
要是简单来说的话那就是 Python 就是这么设计的,而且不这么设计的话会带来别的问题 :)
RIcter
2015-08-08 06:15:21 +08:00
a 是 A 的 instance,對 a 做的操作一般來說是不會影響到 A 的⋯
Feiox
2015-08-08 09:33:16 +08:00
每个实例会复制一份类属性,你修改的只是这个属性的副本,并不会影响其本身。如果想修改类属性,请使用 A.cls_attr += 1 的方式修改。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/211484

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX