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;
}
1
x1x1 2022-06-17 15:28:33 +08:00
objA 实际执行的是根据 class A 创建出来的对象,一个固定的内存地址
|
2
rationa1cuzz 2022-06-17 15:32:58 +08:00 1
tmp1 和 tmp2 共用了 objA 的内存地址
|
3
x1x1 2022-06-17 15:33:29 +08:00 1
第一个问题:为什么 tmp2.objA.title 也变了? 因为 tmp1.objA 和 tmp2.objA 在内存中都是指向一个实例化的对象,修改后自然会变
第二个问题:但为什么 tmp2.title 没有变? tmp1 和 tmp2 虽然是来自同一个类,但是是两个不同的对象,修改 tmp1 的 title 属性,tmp2 不会变 |
5
JYLu 2022-06-17 17:34:34 +08:00 via Android
@x1x1 请问 #3 是不是要区分基本类型和引用类型?字符串是基本类型,所以在赋值的时候创建的是一个新的副本,但是用户定义的 A 类是引用类型,赋值的时候传递的是地址?
|
6
x1x1 2022-06-17 17:56:08 +08:00
@JYLu Python 变量全都是指向内存中的某个对象的指针。字符串是不可变类型,也就是你说的基本类型,一旦值发生改变时,当前变量指向的地址也会修改。自定义的 class 属于可变类型,可以理解为引用类型,值发生修改时(重新赋值除外),当前变量指向地址没变,地址指向的内容发生改变。
|
8
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) |