鱼C论坛

 找回密码
 立即注册
查看: 2734|回复: 5

[已解决]关于类和对象的问题

[复制链接]
发表于 2020-9-15 13:46:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
class A():
    lst1=[1,2,3]
    lst2=[1,2,3]
    def __init__(self):
        self.lst1=10
        self.lst2[2]=10
a=A()
print(A.lst1)
print(a.lst1)
print(A.lst2)
print(a.lst2)
print(A.lst1)          # 打印结果 [1, 2, 3]
print(a.lst1)        # 打印结果 10        
print(A.lst2)        # 打印结果 [1, 2, 10]
print(a.lst2)         # 打印结果 [1, 2, 10]

为什么 A.lst1和a.lst1打印结果不一样,但 A.lst2 和a.lst2 结果又一样呢
最佳答案
2020-9-15 19:33:39
本帖最后由 sunrise085 于 2020-9-15 19:37 编辑

heidern0612 发表于 2020-9-15 15:27
类实例化后会有个特殊效果。

在本身属性没有的情况下会去类中查找。


2楼说的才有点道理,但不是被替换,一个是被覆盖屏蔽了,一个是被修改了
在__init__中,self.lst1=10,是直接定义实例属性lst1,并对其进行赋值这就屏蔽了类属性lst1,当用实例对象懂lst1的时候调用的就是实例属性lst1,而非类属性lst1
在__init__中,self.lst2[2]=10,相当于直接修改实例属性lst2[2],要修改,那就需要先找找是否定义了,若没有定义,则会报错,会先找实例属性lst2,发现没找到,然后再向上一层找类属性lst2,找到了!然后就对其进行了修改。这相当于实际上没有实例属性lst2,一直使用的都是类实例属性lst2
所以才会出现如此运行结果。

通过此例可以看出,类实例化中,列表是全局的,不管你怎么实例化,修改的都是类中原来的属性。

你这句话是不对的,你可以看看下面的运行结果
class A():
    lst1=[1,2,3]
    lst2=[1,2,3]
    def __init__(self):
        self.lst1=10
        self.lst2=[3,5,7]

a=A() #在这里的时候,类属性lst2就已经被修改了。而不是想你说的,到第二次打印a.lst1的时候才覆盖。 
print(A.lst1)
print(a.lst1)
print(A.lst2)
print(a.lst2)
对于可变对象和不可变对象修改和定义的一些区别,尤其是在函数中修改,可以看看我写的这个帖子的第四部分。或许能理解的更好一些
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-15 15:24:11 | 显示全部楼层
self.lst1 = 10进行绑定了类的实例属性,也就是替换了原来的lst1,而self.lst2没有被替换,只是做了修改,把3换成了10,也就是self.lst2[2] = 10的作用,结果当然不一样啦,一个被替换,一个被修改!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-15 15:27:10 | 显示全部楼层
类实例化后会有个特殊效果。

在本身属性没有的情况下会去类中查找。

第一次打印A.lst1的时候,因为没有实例化,所以A默认调用的是自己功能内的lst1;

第二次打印a.lst1的时候,实例化,lst1和lst2都有了值,覆盖了上面类实例化中的lst1和lst2,也覆盖了类中的lst1和lst2.

第三次打印A.lst2的时候,原理见上面一条。

第四次打印a.lst2的时候,原理见上上面一条。


通过此例可以看出,类实例化中,列表是全局的,不管你怎么实例化,修改的都是类中原来的属性。

实际应用中可以用于实现网页登录特征。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-15 19:33:39 | 显示全部楼层    本楼为最佳答案   
本帖最后由 sunrise085 于 2020-9-15 19:37 编辑

heidern0612 发表于 2020-9-15 15:27
类实例化后会有个特殊效果。

在本身属性没有的情况下会去类中查找。


2楼说的才有点道理,但不是被替换,一个是被覆盖屏蔽了,一个是被修改了
在__init__中,self.lst1=10,是直接定义实例属性lst1,并对其进行赋值这就屏蔽了类属性lst1,当用实例对象懂lst1的时候调用的就是实例属性lst1,而非类属性lst1
在__init__中,self.lst2[2]=10,相当于直接修改实例属性lst2[2],要修改,那就需要先找找是否定义了,若没有定义,则会报错,会先找实例属性lst2,发现没找到,然后再向上一层找类属性lst2,找到了!然后就对其进行了修改。这相当于实际上没有实例属性lst2,一直使用的都是类实例属性lst2
所以才会出现如此运行结果。

通过此例可以看出,类实例化中,列表是全局的,不管你怎么实例化,修改的都是类中原来的属性。

你这句话是不对的,你可以看看下面的运行结果
class A():
    lst1=[1,2,3]
    lst2=[1,2,3]
    def __init__(self):
        self.lst1=10
        self.lst2=[3,5,7]

a=A() #在这里的时候,类属性lst2就已经被修改了。而不是想你说的,到第二次打印a.lst1的时候才覆盖。 
print(A.lst1)
print(a.lst1)
print(A.lst2)
print(a.lst2)
对于可变对象和不可变对象修改和定义的一些区别,尤其是在函数中修改,可以看看我写的这个帖子的第四部分。或许能理解的更好一些
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-16 07:29:16 | 显示全部楼层
sunrise085 发表于 2020-9-15 19:33
2楼说的才有点道理,但不是被替换,一个是被覆盖屏蔽了,一个是被修改了
在__init__中,self.lst1=10 ...

不管有没有,替换还是屏蔽啥的。

在实例化属性没有的情况下,才会去类中找,有的话就是自己私有的,跟类属性不混淆。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-16 08:57:51 | 显示全部楼层
看不懂  来围观下哈 。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-11 04:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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