V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
LinkedIn
yaron
V2EX  ›  问与答

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

  •  
  •   yaron · 100 天前 · 431 次点击
    这是一个创建于 100 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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;
    }
    
    8 条回复    2022-06-18 01:24:47 +08:00
    x1x1
        1
    x1x1  
       100 天前
    objA 实际执行的是根据 class A 创建出来的对象,一个固定的内存地址
    rationa1cuzz
        2
    rationa1cuzz  
       100 天前   ❤️ 1
    tmp1 和 tmp2 共用了 objA 的内存地址
    x1x1
        3
    x1x1  
       100 天前   ❤️ 1
    第一个问题:为什么 tmp2.objA.title 也变了? 因为 tmp1.objA 和 tmp2.objA 在内存中都是指向一个实例化的对象,修改后自然会变
    第二个问题:但为什么 tmp2.title 没有变? tmp1 和 tmp2 虽然是来自同一个类,但是是两个不同的对象,修改 tmp1 的 title 属性,tmp2 不会变
    yaron
        4
    yaron  
    OP
       100 天前
    @x1x1 谢谢,明白了!
    JYLu
        5
    JYLu  
       100 天前 via Android
    @x1x1 请问 #3 是不是要区分基本类型和引用类型?字符串是基本类型,所以在赋值的时候创建的是一个新的副本,但是用户定义的 A 类是引用类型,赋值的时候传递的是地址?
    x1x1
        6
    x1x1  
       100 天前
    @JYLu Python 变量全都是指向内存中的某个对象的指针。字符串是不可变类型,也就是你说的基本类型,一旦值发生改变时,当前变量指向的地址也会修改。自定义的 class 属于可变类型,可以理解为引用类型,值发生修改时(重新赋值除外),当前变量指向地址没变,地址指向的内容发生改变。
    JYLu
        7
    JYLu  
       100 天前 via Android
    @x1x1 谢谢.
    MiketsuSmasher
        8
    MiketsuSmasher  
       100 天前
    B.objA 是一个类属性,在类创建时就被赋值为 A 的实例,在创建 B 的实例时,objA 作为类属性不会被改变。
    所以 tmp1.objA 、tmp2.objA 和 B.objA 都是同一个实例化的对象。
    你可以验证一下:assert id(tmp1.objA) == id(tmp2.objA)
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4593 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 03:21 · PVG 11:21 · LAX 20:21 · JFK 23:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.