谨慎修改Python的类属性,慎重对实例属性和类属性使用相同的名字
谨慎修改Python的类属性
- Python的类和类实例都是可变对象,可以随时给属性赋值,并且在原处修改。
- 在对类属性进行修改时需要特别小心,因为所有的类实例都继承共享类属性,除非实例本身存在和类属性同名的属性。对类属性进行修改,会影响到所有由这个类生成的实例。
- 在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
下边是一个测试的例子
1 #-*- coding:utf8 -*- 2 3 class B: 4 testlist = [111,222] 5 6 if __name__ == "__main__": 7 8 b1=B() 9 b2=B() 10 # 打印实例testlist的参数 11 print("-----step 1-----") 12 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 13 print("instance b1.testlist:",b1.testlist ,id(b1.testlist)) 14 print("instance b2.testlist:",b2.testlist ,id(b2.testlist)) 15 #修改类的属性 16 B.testlist.append(123) 17 # 类的属性被修改,实例的属性也会变化 18 print("-----step 2-----") 19 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 20 print("instance b1.testlist:",b1.testlist ,id(b1.testlist)) 21 print("instance b2.testlist:",b2.testlist ,id(b2.testlist)) 22 23 # 通过实例修改的类变量,其他实列的类变量值也会发生变化 24 b1.testlist.append("b1") 25 print("-----step 3-----") 26 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 27 print("instance b1.testlist:",b1.testlist,id(b1.testlist)) 28 print("instance b2.testlist:",b2.testlist,id(b2.testlist)) 29 30 # 当对实例的属性重新赋值,则此实例的属性变化不会在影响类和其他实例 31 b1.testlist=["b1"] 32 b1.testlist.append("b1") 33 print("-----step 4-----") 34 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 35 print("instance b1.testlist:",b1.testlist,id(b1.testlist)) 36 print("instance b2.testlist:",b2.testlist,id(b2.testlist)) 37 38 # 当对类的属性重新赋值,实例的属性会同时发生变化,除非载此之前实例的属性已经被重新赋值 39 B.testlist=["B"] 40 B.testlist.append("B") 41 print("-----step 5-----") 42 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 43 print("instance b1.testlist:",b1.testlist,id(b1.testlist)) 44 print("instance b2.testlist:",b2.testlist,id(b2.testlist)) 45 46 # 让我们删除b1的实例属性试一下,b1的实例属性有何类属性保持一致了 47 del b1.testlist 48 print("-----step 6-----") 49 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 50 print("instance b1.testlist:",b1.testlist,id(b1.testlist)) 51 print("instance b2.testlist:",b2.testlist,id(b2.testlist)) 52 53 # 当删除类属性后,类属性和实例的属性都被删除,除非实例的属性被提前赋值 54 b1.testlist=['new b1'] 55 del B.testlist 56 print("-----step 7-----") 57 try: 58 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 59 except Exception as e: 60 print(e) 61 try: 62 print("instance b1.testlist:",b1.testlist,id(b1.testlist)) 63 except Exception as e: 64 print(e) 65 try: 66 print("instance b2.testlist:",b2.testlist,id(b2.testlist)) 67 except Exception as e: 68 print(e) 69 70 # 如果实例没有对该属性重新赋值,则对此实例属性的删除将会失败 71 print("-----step 8-----") 72 B.testlist=["new B"] 73 try: 74 del b2.testlist 75 print("del") 76 except Exception as e: 77 print("del failed") 78 print(e) 79 try: 80 print("class B.testlist: ",B.testlist ,id(B.testlist) ) 81 except Exception as e: 82 print(e) 83 try: 84 print("instance b1.testlist:",b1.testlist,id(b1.testlist)) 85 except Exception as e: 86 print(e) 87 try: 88 print("instance b2.testlist:",b2.testlist,id(b2.testlist)) 89 except Exception as e: 90 print(e) 91 92 """ 93 -----step 1----- 94 ('class B.testlist: ', [111, 222], 58725704L) 95 ('instance b1.testlist:', [111, 222], 58725704L) 96 ('instance b2.testlist:', [111, 222], 58725704L) 97 -----step 2----- 98 ('class B.testlist: ', [111, 222, 123], 58725704L) 99 ('instance b1.testlist:', [111, 222, 123], 58725704L) 100 ('instance b2.testlist:', [111, 222, 123], 58725704L) 101 -----step 3----- 102 ('class B.testlist: ', [111, 222, 123, 'b1'], 58725704L) 103 ('instance b1.testlist:', [111, 222, 123, 'b1'], 58725704L) 104 ('instance b2.testlist:', [111, 222, 123, 'b1'], 58725704L) 105 -----step 4----- 106 ('class B.testlist: ', [111, 222, 123, 'b1'], 58725704L) 107 ('instance b1.testlist:', ['b1', 'b1'], 58768712L) 108 ('instance b2.testlist:', [111, 222, 123, 'b1'], 58725704L) 109 -----step 5----- 110 ('class B.testlist: ', ['B', 'B'], 58769288L) 111 ('instance b1.testlist:', ['b1', 'b1'], 58768712L) 112 ('instance b2.testlist:', ['B', 'B'], 58769288L) 113 -----step 6----- 114 ('class B.testlist: ', ['B', 'B'], 58769288L) 115 ('instance b1.testlist:', ['B', 'B'], 58769288L) 116 ('instance b2.testlist:', ['B', 'B'], 58769288L) 117 -----step 7----- 118 class B has no attribute 'testlist' 119 ('instance b1.testlist:', ['new b1'], 58768712L) 120 B instance has no attribute 'testlist' 121 -----step 8----- 122 del failed 123 B instance has no attribute 'testlist' 124 ('class B.testlist: ', ['new B'], 58769288L) 125 ('instance b1.testlist:', ['new b1'], 58768712L) 126 ('instance b2.testlist:', ['new B'], 58769288L) 127 """
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)