Python3-类属性和实例属性
类属性和实例属性概念
一个类实例化后,实例是一个对象,它有属性。不要忘记,Python中的类也是一个对象,且也有属性。所以就有了“类属性”和“实例属性”两个属性。
>>> class A():
x = 7
定义了一个简单的类,其中x是类属性。在类A中,变量x所引用的对象,能够直接通过类调用。或者说x是类A的属性,这就是所谓的“类属性”。类属性仅限于此——类中的变量还有另外的称呼,如静态数据。
>>> B = A()
>>> B.x
7
将类A实例化,通过实例B也可以得到属性(B.x),这个属性叫作“实例属性”。
两种属性相互之间的影响
>>> B.x += 1
>>> B.x
8
>>> A.x
7
由此可知,实例属性(B.x)更新了,类属性(A.x)没有改变。这至少说明,类属性不会被实例属性左右,也可以进一步说明“类属性与实例属性无关”(这句话不能理解为“类属性”和“实例属性”互不相关,如果要这么理解,按照更严格的逻辑,应该还要看看修改A.x变化是否影响到 B.x)。
那么,B.x+=1的本质是什么呢? 其本质是实例B又建立了一个新的属性,但是这个属性(新的 B.x)居然与原来的属性(旧的B.x)重名,所以,原来的B.x就 被“遮盖了”,只能访问到新的B.x,它的值是8。既然新的B.x“遮 盖”了旧的B.x,如果删除它,旧的就会显现出来。
>>> B.x
8
>>> del B.x
>>> B.x
7
>>> class Person():
name = "张三"
新建一个Person类,其中有类属性name。
>>> person = Person()
>>> person.age = 17
>>> person.age
17
实例化person对象,且对象新加一个age属性。那么类型属性会包含age这个属性吗?
>>> Person.age
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
Person.age
AttributeError: type object 'Person' has no attribute 'age'
上面说明,实列化对象新添属性不会影响类属性的变化。
>>> Person.name
'张三'
>>> person.name
'张三'
>>> Person.name = '李四'
>>> person.name
'李四'
上面说明:实例属性的值随着类属性的值变化而改变了。
综上类属性确实不受实例对象的影响,但实例对象受到类属性左右。但这是有前提条件的。前面例子变量不可变量(整数和字符串),对于可变变量的相互影响仍未可知。
不可变属性相互之间的影响
>>> class Student():
course = ['英语','数学','语文']
定义一个Student类,内含可变属性。
>>> student = Student()
>>> Student.course
['英语', '数学', '语文']
>>> student.course
['英语', '数学', '语文']
>>> Student.course.append('体育')
>>> Student.course
['英语', '数学', '语文', '体育']
>>> student.course
['英语', '数学', '语文', '体育']
>>> student.course.append('历史')
>>> student.course
['英语', '数学', '语文', '体育', '历史']
由上可知结论:当类中变量引用的是可变对象时,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。