最近学习到类这块的时候,感觉理解有点跟不上了,还是通过实例来理解吧:
一、访问类属性
class Foo(object): #定义一个类
x = 2 #类属性(静态)
foo = Foo() #类的实例化
print(foo.x) #通过实例来访问类属性
print(Foo.x) #通过类来访问类属性
foo.x = 3 #创建一个实例属性
print(foo.x)
print(Foo.x)
Foo.x = 4 #改变类属性的值
print(foo.x)
print(Foo.x)
得到结果:
2
2
3
2
3
4
一点点来分析,访问类属性的话,有两种方式,一种是通过实例来访问类属性(如程序第5行),一种是通过类来访问(如程序第6行)。
但是如果想要改变类属性的数值(对于静态类属性),则只能通过类来进行访问(第10行)。而通过实例来访问的话,则只会生成一个实例属性,而不是对类属性进行改变(第7行)。
通过给与类属性(第2行)同名的实例属性(第7行)赋值,会将类属性隐藏掉(第8行),而此时访问类属性则只能通过类进行访问(第9行)。
很绕口,总结来说:
1,访问类属性可以通过类与实例两种方式访问;
2,修改类属性的数值(静态)只能通过类进行修改;
3,如果通过实例进行修改的话,则会创建出一个同名的实例属性;
4,此时在想访问类属性,则只能通过类进行访问;
5,如果通过实例进行访问的会,则会访问到实例属性,把同名的类属性隐藏了。
二、类属性为可变的
如果类中定义的类属性为可变的,比如列表,字典:
class Foo(object): #定义类 x = [1,2,3] foo = Foo() print(foo.x[0]) print(Foo.x[0]) foo.x[0] = 4 print(foo.x[0]) print(Foo.x[0]) Foo.x[1] = 5 print(foo.x[1]) print(Foo.x[1])
得到结果:
1
1
4
4
5
5
从中可以看出,对于可变的类属性,两种访问方式都可以改变类属性的值。
想想应该还是跟类属性的性质有关吧,如果是不可变对象,采用实例方式进行访问,应该是重新分配了一个类属性的内存给它,copy了一份。
而类属性为可变类型的话,采用实例方式进行访问,只是把类属性的地址给了它。
简要如下例:
a = 1
b = a
print(a)
print(b)
a = 2
print(a)
print(b)
得到结果:
1
1
2
1