白白白白丶白 发表于 2020-7-11 12:08:07

日常送分,小白问题,类。

当使用__init__定义实例变量的时候,类变量是不是没必要定义了,这两个能同时用吗

suchocolate 发表于 2020-7-11 12:10:56

都有必要,能同时用,但不要同名。

qiuyouzhi 发表于 2020-7-11 12:14:38

实例属性和类属性不一样,看你想用类调用这个属性还是用实例调用这个属性。
可以同时用。

Twilight6 发表于 2020-7-11 12:20:14

本帖最后由 Twilight6 于 2020-7-11 12:32 编辑




同时完全没毛病

类变量,对所有这个类实例对象共享的属性,只要有一个实例改变了类属性,该类所有的实例变量都会改变

比如,我定义了一个 A 类,a、b、c 都是 A 类的实例对象,当你对 a里面的类属性 + 100 时候,b、c 的这个类属性也会加一百,因为类属性是属于类本体的,所以他们所有实例对象都是共享这个类属性的

实例属性就不会,每个实例对象互不影响、互不干涉

比如说:
class A:
    count = 0
    def __init__(self):
      A.count += 1
      self.a = 100

x = A()
y = A()
print(x.count)
z = A()
print(x.count)

我们发现输出结果为:
2
3

就是因为类的属性发生改变,会影响所有这个类的实例对象的类属性值,而我们每次读取的都是 x 实例对象


小甲鱼的铁粉 发表于 2020-7-11 12:33:33

{:10_269:}类和对象好难

白白白白丶白 发表于 2020-7-11 13:28:51

Twilight6 发表于 2020-7-11 12:20
同时完全没毛病

类变量,对所有这个类实例对象共享的属性,只要有一个实例改变了类属性,该类所有 ...

那就是想设定一个属性是所有实例 对象的属性的时候就用类属性,要是互不影响就设置实例属性

Twilight6 发表于 2020-7-11 13:29:31

白白白白丶白 发表于 2020-7-11 13:28
那就是想设定一个属性是所有实例 对象的属性的时候就用类属性,要是互不影响就设置实例属性



嗯嗯

白白白白丶白 发表于 2020-7-11 13:30:14

小甲鱼的铁粉 发表于 2020-7-11 12:33
类和对象好难

慢慢看呗

白白白白丶白 发表于 2020-7-11 14:34:43

Twilight6 发表于 2020-7-11 13:29
嗯嗯

还有个小问题,百度的时候看到有个成员变量,python里有这个定义吗

Twilight6 发表于 2020-7-11 14:37:07

白白白白丶白 发表于 2020-7-11 14:34
还有个小问题,百度的时候看到有个成员变量,python里有这个定义吗


就是实例变量

白白白白丶白 发表于 2020-7-11 14:39:50

Twilight6 发表于 2020-7-11 14:37
就是实例变量

好的,谢谢

Twilight6 发表于 2020-7-11 14:40:09

白白白白丶白 发表于 2020-7-11 14:39
好的,谢谢

没事~客气了

白白白白丶白 发表于 2020-7-11 16:50:47

Twilight6 发表于 2020-7-11 14:40
没事~客气了

我在看别的知识点的时候拿上面的代码作示例
>>> class A:
        count = 0
        def __init__(self):
                A.b = 1
                A.count += 1
                self.a = 100
>>> x = A()
>>> y = A()
>>> x.count= 3
>>> y.count
2
>>> A.count = 5
>>> x.count
3
>>> y.count
5

改了一点, 上面在__init__方法里面的A.b应该是类变量把,

但是我将x.count = 3之后为什么y.count还是2

改了A.count = 5后,只有y.count跟着改变了。

后来我又重启了idle重新试了一次,我发现在实例方法中赋值了类变量后,他就不会跟着类变量的改变去变了

Twilight6 发表于 2020-7-11 17:07:11

白白白白丶白 发表于 2020-7-11 16:50
我在看别的知识点的时候拿上面的代码作示例




类属性要对类来赋值

你 x.count= 3,是对 x 实例对象赋值了一个 count 实例属性

你要改变类属性的值应该这样 A.count = 10

白白白白丶白 发表于 2020-7-11 17:38:28

Twilight6 发表于 2020-7-11 17:07
类属性要对类来赋值

你 x.count= 3,是对 x 实例对象赋值了一个 count 实例属性


A.count = 10之后,x的count属性仍然是3   但是y的count属性就跟着变了

Twilight6 发表于 2020-7-11 17:39:02

白白白白丶白 发表于 2020-7-11 17:38
A.count = 10之后,x的count属性仍然是3

是因为你的实例属性和类属性同名

Twilight6 发表于 2020-7-11 17:39:56

白白白白丶白 发表于 2020-7-11 17:38
A.count = 10之后,x的count属性仍然是3   但是y的count属性就跟着变了

属性查找的顺序是先找实例对象,然后找类对象,在然后找类对象的父类,直到找到返回或者没找到报错

白白白白丶白 发表于 2020-7-11 17:45:46

Twilight6 发表于 2020-7-11 17:39
属性查找的顺序是先找实例对象,然后找类对象,在然后找类对象的父类,直到找到返回或者没找到报错

>>> class A:
        count = 0
        def __init__(self):
                A.b = 1
                A.count += 1
                self.a = 100
>>> x = A()
>>> y = A()
>>> A.count = 10
>>> x.count
10
>>> y.count
10
>>> x.count = 5
>>> A.count = 20
>>> x.count
5

那这个,当没有x.count = 5的时候,xy 的count的值都是跟这A.count变的。

当赋值后,x.count的值就固定了,这就是因为类属性和实例属性同名的原因导致的吗

Twilight6 发表于 2020-7-11 17:50:48

白白白白丶白 发表于 2020-7-11 17:45
那这个,当没有x.count = 5的时候,xy 的count的值都是跟这A.count变的。

当赋值后,x.count ...


你理解下我楼上说的哈,你获取属性的时候首先Python 要去对象里面查找属性

而查找顺序是最先对实例对象查找,然后在到实例对象的类,然后到实例对象类的父类,只要过程中有找到,就直接返回这个属性对于的 value
那这个,当没有x.count = 5的时候,xy 的count的值都是跟这A.count变的。

就算有 x.count = 5 , 这个类属性还是会随着 A中的类属性变化而变化的,但是有了 count ,导致你在实例对象中已经查找到了你所需要的属性,所以返回的是 x 类中的 count ,此时你改变 count 都是改变 x 的实力属性了

当赋值后,x.count的值就固定了,这就是因为类属性和实例属性同名的原因导致的吗

是的,但是类变量 count 还是会变化的

白白白白丶白 发表于 2020-7-11 17:53:20

Twilight6 发表于 2020-7-11 17:50
你理解下我楼上说的哈,你获取属性的时候首先Python 要去对象里面查找属性

而查找顺序是最先对实例 ...

奥。按照上面的顺序访问到需要的值之后,类变量中的count就不会被读取了。懂了。谢谢
页: [1] 2
查看完整版本: 日常送分,小白问题,类。