zy8818 发表于 2022-11-3 23:32:13

类变量和对象变量的问题

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

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



a=Test()
b=Test()
print("对象变量没有赋值前:")
print("a.name->id=\t",id(a.name),"a.name=",a.name)
print("b.name->id=\t",id(b.name),"b.name=",b.name)
print("Test.name->id=\t",id(Test.name),"Test.name=",Test.name)
a.name="a1"
Test.name="Test2"
print("对象a,Test.name 赋值后:")
print("a.name->id=\t",id(a.name),"a.name=",a.name)
print("b.name->id=\t",id(b.name),"b.name=",b.name)
print("Test.name->id=\t",id(Test.name),"Test.name=",Test.name)
a.name="a2"
b.name="b1"
Test.name="Test3"
print("对象a,对象b,Test.name 赋值后:")
print("a.name->id=\t",id(a.name),"a.name=",a.name)
print("b.name->id=\t",id(b.name),"b.name=",b.name)
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

zy8818 发表于 2022-11-3 23:38:37

感觉python的语法一点都不严谨,还搞个伪私有属性
对象变量多次赋值每次地址都不一样,
这个数据全部是c++里面new出来的吗,用一次就释放了

jackz007 发表于 2022-11-3 23:58:22

本帖最后由 jackz007 于 2022-11-4 00:00 编辑

类变量和对象变量的问题
在对象变量没有赋值的时候地址指向的是类变量
       楼主,作为 C++ 的高手,请你解释一下,这两句的意思,什么叫类变量什么叫对象变量?
       这两个东西在你所给出的代码中,如何 "对号入座"???

阿奇_o 发表于 2022-11-4 00:33:58

本帖最后由 阿奇_o 于 2022-11-4 00:41 编辑

zy8818 发表于 2022-11-3 23:38
感觉python的语法一点都不严谨,还搞个伪私有属性
对象变量多次赋值每次地址都不一样,
这个数据全部是c+ ...

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

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

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

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

zy8818 发表于 2022-11-4 10:21:39

谁也没有自称大佬,没有最强,只有更强
这个是我自己的理解,不代表如何意见,想解决问题就说,不想就不说
类变量:就是用类名访问的,不属于任何一个对象
对象变量:就是某一个对象专属的,其他对象访问不到的,类名也是访问不到的

zy8818 发表于 2022-11-4 10:33:42

python本身就是脚本语言,至于内存地址什么的本身就是一个笑话,
可以这么理解把,这是全部都是脚本控制的,我也不奢望他内存地址固定了,至少小甲鱼是这么说的,这是一门脚本语言
既然他是这样设计的,我们就暂时这样理解把

hrpzcf 发表于 2022-11-4 10:39:52

类变量:正确说法是类属性
对象变量:正确说法是实例属性

创建类实例后,该实例会拥有和类相同名称的属性,而且属性的值是指向类属性值的内存地址,对实例属性赋值后,实例属性指向新值的内存地址,类属性之前是什么样的还是什么样的,这个不难理解。

阿奇_o 发表于 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面向对象相关问题时,使用 类属性,实例属性/对象属性 的叫法,要比"类变量"、"对象变量"这一的叫法,更准确、也更有助理解。
因为"变量"的范畴太大了,也"太基本"了,更多适合在讨论"基础数据类型"的时候使用该叫法。(当然不同的叫法而已,随君喜欢,只是交流时或增阻碍)

zy8818 发表于 2022-11-4 15:01:44

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

这么和你说把,每个人的叫法都不一样
我说的对象就是实例化的对象
你想要知道原理我可以和你讲一下,但是不一定是对的
我个人理解的

zy8818 发表于 2022-11-4 15:14:58

本帖最后由 zy8818 于 2022-11-4 15:17 编辑

总之,
python
带self就是(实例属性),实例才可以用实例名直接访问
不带self的就是(类属性),直接用类名可以访问
我们写的类代码是存在一个专属代码内存空间里面
类属性的也进行了按照 类代码->类属性模板->内存实例化,开辟了一个类属性的空间
self属性的也进行了按照 类代码->self属性模板->内存实例化,开辟了一个self属性的空间

tommyyu 发表于 2022-11-4 15:22:43

zy8818 发表于 2022-11-4 15:14
总之,
python
带self就是(实例属性),实例才可以用实例名直接访问


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

>>> C.a = 0
>>> a = C()
>>> b = C()
>>> c = C()
>>> c.a += 10
>>> c.a
10
>>> C.a += 100
>>> C.a
100
>>> a.a
100
>>> b.a
100
>>>

zy8818 发表于 2022-11-4 18:04:31

tommyyu 发表于 2022-11-4 15:22
实例对象属性有时候是和类属性绑定在一起的,小甲鱼旧版教材中举过例子

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

但是不加self的函数就只能类名使用了,不能给实例对象使用了
页: [1]
查看完整版本: 类变量和对象变量的问题