鱼C论坛

 找回密码
 立即注册
查看: 2299|回复: 11

[已解决]类变量和对象变量的问题

[复制链接]
发表于 2022-11-3 23:32:13 | 显示全部楼层 |阅读模式

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

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

x
类变量和对象变量的问题
在对象变量没有赋值的时候地址指向的是类变量
对象变量赋值之后才才是真正的对象变量
那为什么对象变量二次重新赋值后地址还是变化了

  1. class Test:
  2.     name="Test"  #这个到底是类变量还是对象变量
  3.     def printTest():
  4.         print("类静态函数,类名.函数名调用,对象不能调用")



  5. a=Test()
  6. b=Test()
  7. print("对象变量没有赋值前:")
  8. print("a.name->id=\t",id(a.name),"a.name=",a.name)
  9. print("b.name->id=\t",id(b.name),"b.name=",b.name)
  10. print("Test.name->id=\t",id(Test.name),"Test.name=",Test.name)
  11. a.name="a1"
  12. Test.name="Test2"
  13. print("对象a,Test.name 赋值后:")
  14. print("a.name->id=\t",id(a.name),"a.name=",a.name)
  15. print("b.name->id=\t",id(b.name),"b.name=",b.name)
  16. print("Test.name->id=\t",id(Test.name),"Test.name=",Test.name)
  17. a.name="a2"
  18. b.name="b1"
  19. Test.name="Test3"
  20. print("对象a,对象b,Test.name 赋值后:")
  21. print("a.name->id=\t",id(a.name),"a.name=",a.name)
  22. print("b.name->id=\t",id(b.name),"b.name=",b.name)
  23. print("Test.name->id=\t",id(Test.name),"Test.name=",Test.name)
复制代码


运行结果
对象变量没有赋值前:
a.name->id=         1886594481840 a.name= Test
b.name->id=         1886594481840 b.name= Test
Test.name->id=         1886594481840 Test.name= Test
对象a,Test.name 赋值后:
a.name->id=         1886594597168 a.name= a1
b.name->id=         1886594597232 b.name= Test2
Test.name->id=         1886594597232 Test.name= Test2
对象a,对象b,Test.name 赋值后:
a.name->id=         1886594597296 a.name= a2
b.name->id=         1886594597360 b.name= b1
Test.name->id=         1886594597424 Test.name= Test3
最佳答案
2022-11-4 00:33:58
本帖最后由 阿奇_o 于 2022-11-4 00:41 编辑
zy8818 发表于 2022-11-3 23:38
感觉python的语法一点都不严谨,还搞个伪私有属性
对象变量多次赋值每次地址都不一样,
这个数据全部是c+ ...


说的好像你是精通C++, Java, Python等众多语言的编程大佬似的。。

个人观点:不是Python语法不严谨,只是你还不太熟悉它而已。

简单回答一下:关于 类变量、对象变量
    类变量(或叫"类属性"):就是在定义类时,最前面,没带self的那些变量名字。比如你这里的 name  就是类变量。
    对象变量(或更多是叫"实例变量"或"实例属性"):就是那些 带有self的变量,比如 self.age
    值得注意的是:实例对象也可以使用 类变量。即 没定义self.name,但有类变量name,实例obj也可以obj.name

至于什么内存,什么对象地址的东东,实际中都不用你管。只要区别开:什么操作是 就地改变(操作原对象),什么操作是 返回新的对象 即可。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-11-3 23:38:37 | 显示全部楼层
感觉python的语法一点都不严谨,还搞个伪私有属性
对象变量多次赋值每次地址都不一样,
这个数据全部是c++里面new出来的吗,用一次就释放了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-3 23:58:22 | 显示全部楼层
本帖最后由 jackz007 于 2022-11-4 00:00 编辑
类变量和对象变量的问题
在对象变量没有赋值的时候地址指向的是类变量

       楼主,作为 C++ 的高手,请你解释一下,这两句的意思,什么叫
类变量
什么叫
对象变量

       这两个东西在你所给出的代码中,如何 "对号入座"???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-4 00:33:58 | 显示全部楼层    本楼为最佳答案   
本帖最后由 阿奇_o 于 2022-11-4 00:41 编辑
zy8818 发表于 2022-11-3 23:38
感觉python的语法一点都不严谨,还搞个伪私有属性
对象变量多次赋值每次地址都不一样,
这个数据全部是c+ ...


说的好像你是精通C++, Java, Python等众多语言的编程大佬似的。。

个人观点:不是Python语法不严谨,只是你还不太熟悉它而已。

简单回答一下:关于 类变量、对象变量
    类变量(或叫"类属性"):就是在定义类时,最前面,没带self的那些变量名字。比如你这里的 name  就是类变量。
    对象变量(或更多是叫"实例变量"或"实例属性"):就是那些 带有self的变量,比如 self.age
    值得注意的是:实例对象也可以使用 类变量。即 没定义self.name,但有类变量name,实例obj也可以obj.name

至于什么内存,什么对象地址的东东,实际中都不用你管。只要区别开:什么操作是 就地改变(操作原对象),什么操作是 返回新的对象 即可。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-11-4 10:21:39 | 显示全部楼层
谁也没有自称大佬,没有最强,只有更强
这个是我自己的理解,不代表如何意见,想解决问题就说,不想就不说
类变量:就是用类名访问的,不属于任何一个对象
对象变量:就是某一个对象专属的,其他对象访问不到的,类名也是访问不到的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-4 10:33:42 | 显示全部楼层
python本身就是脚本语言,至于内存地址什么的本身就是一个笑话,
可以这么理解把,这是全部都是脚本控制的,我也不奢望他内存地址固定了,至少小甲鱼是这么说的,这是一门脚本语言
既然他是这样设计的,我们就暂时这样理解把
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-4 10:39:52 From FishC Mobile | 显示全部楼层
类变量:正确说法是类属性
对象变量:正确说法是实例属性

创建类实例后,该实例会拥有和类相同名称的属性,而且属性的值是指向类属性值的内存地址,对实例属性赋值后,实例属性指向新值的内存地址,类属性之前是什么样的还是什么样的,这个不难理解。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-4 12:50:40 | 显示全部楼层
本帖最后由 阿奇_o 于 2022-11-4 13:00 编辑
zy8818 发表于 2022-11-4 10:21
谁也没有自称大佬,没有最强,只有更强
这个是我自己的理解,不代表如何意见,想解决问题就说,不想就不说 ...


但为什么不这样想:
对象都是某个类的实例,也就是 以这类为模板造出来的,因此实例对象自然可以使用 该类所拥有的属性——类属性(类变量),自然实例就可以访问了。
就好比,Animal类都有"能动的"属性,它的实例对象如某只猫cat = Animal() ,这时,这个cat对象,为什么不能使用"能动的"这一"类属性"?
而你说的"对象变量"应该是这个对象专属的,这很合理,Python也是这么做的。我相信所有主流OOP语言都是这样做的。

ps: 个人觉得,在说OOP面向对象相关问题时,使用 类属性,实例属性/对象属性 的叫法,要比"类变量"、"对象变量"这一的叫法,更准确、也更有助理解。
因为"变量"的范畴太大了,也"太基本"了,更多适合在讨论"基础数据类型"的时候使用该叫法。(当然不同的叫法而已,随君喜欢,只是交流时或增阻碍)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-4 15:01:44 | 显示全部楼层
jackz007 发表于 2022-11-3 23:58
楼主,作为 C++ 的高手,请你解释一下,这两句的意思,什么叫什么叫?
       这两个东西在你所 ...

这么和你说把,每个人的叫法都不一样
我说的对象就是实例化的对象
你想要知道原理我可以和你讲一下,但是不一定是对的
我个人理解的
22.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-4 15:14:58 | 显示全部楼层
本帖最后由 zy8818 于 2022-11-4 15:17 编辑

总之,
python
带self就是(实例属性),实例才可以用实例名直接访问
不带self的就是(类属性),直接用类名可以访问
我们写的类代码是存在一个专属代码内存空间里面
类属性的也进行了按照 类代码->类属性模板->内存实例化,开辟了一个类属性的空间
self属性的也进行了按照 类代码->self属性模板->内存实例化,开辟了一个self属性的空间
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-4 15:22:43 | 显示全部楼层
zy8818 发表于 2022-11-4 15:14
总之,
python
带self就是(实例属性),实例才可以用实例名直接访问

实例对象属性有时候是和类属性绑定在一起的,小甲鱼旧版教材中举过例子
  1. >>> class C:
  2.         pass

  3. >>> C.a = 0
  4. >>> a = C()
  5. >>> b = C()
  6. >>> c = C()
  7. >>> c.a += 10
  8. >>> c.a
  9. 10
  10. >>> C.a += 100
  11. >>> C.a
  12. 100
  13. >>> a.a
  14. 100
  15. >>> b.a
  16. 100
  17. >>>
复制代码

评分

参与人数 1荣誉 +5 鱼币 +3 贡献 +3 收起 理由
zy8818 + 5 + 3 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-4 18:04:31 | 显示全部楼层
tommyyu 发表于 2022-11-4 15:22
实例对象属性有时候是和类属性绑定在一起的,小甲鱼旧版教材中举过例子

谢了,兄弟,
我明白了不加self的变量是双属性的
类名直接使用就是类变量
实例对象使用就单独开一个实例对象变量

但是不加self的函数就只能类名使用了,不能给实例对象使用了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-20 06:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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