谨慎修改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 """
复制代码

 

posted @   此间的少年no  阅读(733)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示