先说结论:
1、类变量属于类所有,建议引用时使用类名引用,形如 cls.attr 。也可以使用实例引用 self.attr 。
- 直接修改类变量。各实例未自行修改类变量时,引用到的值都会改变
- 如果在实例中对类变量赋值,会复制一份为实例变量。覆盖了类变量
- 通过实例引用类变量会比较慢
2、实例变量属于实例所有,引用方式形如 self.attr
代码示例如下:
class TestClass:
project_id: str = "类变量"
cluster_id: Optional[str] = None
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}")
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}")
|