请教大佬一个关于 Python 类成员的问题

2022-06-17 15:12:31 +08:00
 yaron
class A(object):
    title = ''
    
class B(object):
    title = ''
    objA = A()

tmp1 = B()
tmp2 = B()

tmp1.title = "21"
tmp1.objA.title = "test"

print(tmp2.title) #空
print(tmp2.objA.title) #test

为什么 tmp2.objA.title 也变了?但为什么 tmp2.title 没有变? 这里的类 B 是不是像 C++的静态成员变量:

class B
{
public:
  static string title;
  static A objA;
}
955 次点击
所在节点    问与答
8 条回复
x1x1
2022-06-17 15:28:33 +08:00
objA 实际执行的是根据 class A 创建出来的对象,一个固定的内存地址
rationa1cuzz
2022-06-17 15:32:58 +08:00
tmp1 和 tmp2 共用了 objA 的内存地址
x1x1
2022-06-17 15:33:29 +08:00
第一个问题:为什么 tmp2.objA.title 也变了? 因为 tmp1.objA 和 tmp2.objA 在内存中都是指向一个实例化的对象,修改后自然会变
第二个问题:但为什么 tmp2.title 没有变? tmp1 和 tmp2 虽然是来自同一个类,但是是两个不同的对象,修改 tmp1 的 title 属性,tmp2 不会变
yaron
2022-06-17 16:03:07 +08:00
@x1x1 谢谢,明白了!
JYLu
2022-06-17 17:34:34 +08:00
@x1x1 请问 #3 是不是要区分基本类型和引用类型?字符串是基本类型,所以在赋值的时候创建的是一个新的副本,但是用户定义的 A 类是引用类型,赋值的时候传递的是地址?
x1x1
2022-06-17 17:56:08 +08:00
@JYLu Python 变量全都是指向内存中的某个对象的指针。字符串是不可变类型,也就是你说的基本类型,一旦值发生改变时,当前变量指向的地址也会修改。自定义的 class 属于可变类型,可以理解为引用类型,值发生修改时(重新赋值除外),当前变量指向地址没变,地址指向的内容发生改变。
JYLu
2022-06-17 18:05:48 +08:00
@x1x1 谢谢.
MiketsuSmasher
2022-06-18 01:24:47 +08:00
B.objA 是一个类属性,在类创建时就被赋值为 A 的实例,在创建 B 的实例时,objA 作为类属性不会被改变。
所以 tmp1.objA 、tmp2.objA 和 B.objA 都是同一个实例化的对象。
你可以验证一下:assert id(tmp1.objA) == id(tmp2.objA)

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

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

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

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

© 2021 V2EX