• python类属性和实例属性的注意点


    先说结论:
    1、类属性属于类所有,建议引用时使用类名引用,形如 cls.attr。当然也可以使用实例引用 self.attr
    通过类名修改类属性后,若各实例未自行修改类属性,则引用到的值都会改变;
    如果即通过实例修改类属性,会复制一份为实例属性,并覆盖类属性;
    通过实例引用类属性会比较慢。
    2、实例变量属于实例所有,引用方式形如self.attr

    class TestClass:
        project_id: str = "类变量"
    
        def __init__(self):
            self.count = 1
    
    # 类变量 当使用实例变量进行类变量赋值之后,就在实例中重新生成了一份变量
    if __name__ == "__main__":
        test_obj1 = TestClass()
        test_obj2 = TestClass()
        # 实例变量
        print("实例变量:")
        print(f"修改前,test_obj1实例变量count内存地址: {id(test_obj1.count)},值:{test_obj1.count}")
        print(f"修改前,test_obj2实例变量count内存地址: {id(test_obj2.count)},值:{test_obj2.count}")
    
        # 类名引用实例变量会报错
        # print(f"修改前,类名引用实例变量count内存地址: {id(TestClass.count)},值:{TestClass.count}")
        test_obj2.count = 2
        test_obj1.count += 3
        print(f"修改后,test_obj1实例变量count内存地址: {id(test_obj1.count)},值:{test_obj1.count}")
        print(f"修改后,test_obj2实例变量count内存地址: {id(test_obj2.count)},值:{test_obj2.count}")
    
        # 类变量
        print("")
        print("类变量:")
        print(f"修改前,test_obj1类变量project_id内存地址: {id(test_obj1.project_id)},值:{test_obj1.project_id}")
        print(f"修改前,test_obj2类变量project_id内存地址: {id(test_obj2.project_id)},值:{test_obj2.project_id}")
        print(f"修改前,类变量project_id内存地址: {id(TestClass.project_id)},值:{TestClass.project_id}")
        # 通过类修改类变量
        print("通过类修改类变量")
        TestClass.project_id = "第一次通过类修改类变量"
        print(f"修改后:test_obj1类变量project_id内存地址: {id(test_obj1.project_id)},值:{test_obj1.project_id}")
        print(f"修改后:test_obj2类变量project_id内存地址: {id(test_obj2.project_id)},值:{test_obj2.project_id}")
        print(f"修改后:类变量project_id内存地址: {id(TestClass.project_id)},值:{TestClass.project_id}")
    
        # 通过实例修改类变量
        print("")
        print("通过实例修改类变量")
        test_obj1.project_id = "实例1类变量"
        test_obj2.project_id = "实例2类变量"
        print(f"修改后:test_obj1类变量project_id内存地址: {id(test_obj1.project_id)},值:{test_obj1.project_id}")
        print(f"修改后:test_obj2类变量project_id内存地址: {id(test_obj2.project_id)},值:{test_obj2.project_id}")
        print(f"修改后:类变量project_id内存地址: {id(TestClass.project_id)},值:{TestClass.project_id}")
    
        # 再次通过类修改类变量,此时不会影响实例中的类变量了
        print("再次通过类修改类变量,此时不会影响实例中的类变量了")
        TestClass.project_id = "第二次通过类修改类变量"
        print(f"修改后:test_obj1类变量project_id内存地址: {id(test_obj1.project_id)},值:{test_obj1.project_id}")
        print(f"修改后:test_obj2类变量project_id内存地址: {id(test_obj2.project_id)},值:{test_obj2.project_id}")
        print(f"修改后:类变量project_id内存地址: {id(TestClass.project_id)},值:{TestClass.project_id}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    实例变量:
    修改前,test_obj1实例变量count内存地址: 2056885266736,值:1
    修改前,test_obj2实例变量count内存地址: 2056885266736,值:1
    修改后,test_obj1实例变量count内存地址: 2056885266832,值:4
    修改后,test_obj2实例变量count内存地址: 2056885266768,值:2

    类变量:
    修改前,test_obj1类变量project_id内存地址: 2056893530448,值:类变量
    修改前,test_obj2类变量project_id内存地址: 2056893530448,值:类变量
    修改前,类变量project_id内存地址: 2056893530448,值:类变量
    通过类修改类变量
    修改后:test_obj1类变量project_id内存地址: 2056893605232,值:第一次通过类修改类变量
    修改后:test_obj2类变量project_id内存地址: 2056893605232,值:第一次通过类修改类变量
    修改后:类变量project_id内存地址: 2056893605232,值:第一次通过类修改类变量

    修改实例引用的类变量,全部实例和类引用的类变量均会改变
    修改后:test_obj1类变量project_id内存地址: 2056890801040,值:实例1类变量
    修改后:test_obj2类变量project_id内存地址: 2056890800368,值:实例2类变量
    修改后:类变量project_id内存地址: 2056893605232,值:第一次通过类修改类变量
    再次修改类变量,此时不会影响实例引用的类变量了
    修改后:test_obj1类变量project_id内存地址: 2056890801040,值:实例1类变量
    修改后:test_obj2类变量project_id内存地址: 2056890800368,值:实例2类变量
    修改后:类变量project_id内存地址: 2056893605328,值:第二次通过类修改类变量

  • 相关阅读:
    在使用 sqlite 时遇到的奇怪问题的正解
    【操作系统】聊聊协程为什么可以支撑高并发服务
    TimeWise-Jira工时管理插件6.0.0发布!对比测评某知名工时插件,谁的数据处理性能更胜一筹?
    vue的学习笔记(1):v-on的使用
    酷开系统,让这个秋天更有温度
    喜大普奔!有软考电子版证书可以正式办理广州落户了!
    深入理解网络协议:通信世界的基石
    Linux 用户系统
    苹果充电时一充一停怎么办_苹果充电线一会儿能充一会儿不能充怎么回事
    广和通5G模组FM650助力阿里云打造无影魔方Pro
  • 原文地址:https://blog.csdn.net/ShenHang_/article/details/126482935