开发者学堂课程【Python 入门 2020年版:类属性和对象属性】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10379
类属性和对象属性
内容介绍:
一、对象属性
二、类属性
一、对象属性
之前的说道 self、魔法方法、内置属性以及把对象当成字典使用。
对象 p1和 p2是通过 Person 类创建出来的实例对象
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
print(‘0x%X,0x%X’,%(id(p1),id(p2)))
运行后打印出两个地址
内存的图画:
现在有两个数据,一个内存内容是张三,还有一个的内存内容是李四。注意刚刚强调的对象 p1和 p2是通过 Person 类创建出来的实例对象,也就是 p1和 p2各自指向一段内存空间。
在这里会有一个小问题,Person 存在哪一个地方?
也就是 p1p2是根据模板创造出来的,找出模板的位置现在修改语句:print(‘0x%X’ % (id(Person)))
代码内容整理:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
print(‘0x%X‘ ,% (id(Person)))
运行后打印出 Perdon 的地址:
也就是现在的实例对象是根据模板创建出来的,有对应的内存地址,所以模板也是有存的内存地址。
CPU 的调动就相当于是在宾馆的前台,看哪一处的内存地址为空,就分配哪一块的内存空间。模板和根据模板创造的对象都保存在内存中,为了区分把 p1、p2成为实例对象,而模板叫类对象。
两个实例对象都是有自己的 name 和 age 属性,发现只要创建一个实例对象,就会保存它们自己的属性,这个每个实例对象都单独保存的属性。
如何获取对象属性的值?能不能获取到主要是看能不能获取到内存,所以直接用语句 print(p1.name)
代码内容整理:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
print(p1.name)
运行结果为:
如果加入 x =p1,就是定义了一个变量 x,曾经讲过在 python 语言中的赋值,等号是内存地址的赋值,所以此时x指向内存空间。就可以通过加入语句print(x.name)拿到张三这个变量内容
代码内容整理:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
print(p1.name)
print(x.name)
运行结果为:
只要能指向同一个内存空间就是可以完成该操作,name 和 age 是对象属性,是每一个实例对象都会单独保存一份的属性。每一个实例对象之间的属性没有关联,互不影响。
就是 p1的张三修改为 jack 对 p2的李四是没有影响的。
二、类属性
类属性是在类对象中定义的,比如现在对 Person 中加入一个 type,命名为人类。
name 和 age 这两个属性是在__init__方法里,以参数的形式定义的。而类属性是在类里面,函数之外的地方来写type = ‘人类‘,这个属性保存在类对象里,其他实例对象都没有保存这个属性。
类属性可以通过类对象和实例对象中获取
1. 通过类对象获取类属性,加入语句 print(Person.type)
代码内容整理:
class Person(object):
type = ‘人类’
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
print(Person.type)
运行结果为:
2. 通过实例对象获取类属性,加入语句 print(p1.type)
代码内容整理:
class Person(object):
type = ‘人类’
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
print(Person.type)
print(p1.type)
print(p2.type)
运行结果为:
刚刚讲过 p1、p2没有保存 type 属性,也就是在 p1、p2中的内存是找不到 type 对象的。
那么它会因为自己没有而自动找到 Person 中的 type
下图为结构示意图:
总之,类属性是可以共享的。
(3)类属性只能通过类对象来修改,实例对象无法修改类属性
如果用p1.type = ‘human’,这个语句可能是在p1的内存空间中加入属性 type:human,或者是在 Person 中 type 的人类改为了 human。
注意这个地方是没有修改类属性的,而是给实例对象中加了一个对象属性。
整理代码内容为:
class Person(object):
type = ‘人类’
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
p1.type = ‘human’
print(p1.type)
运行结果为:
加入语句打印出 p2、Person,print(p2.type),print(Person.type)
运行结果为:最下面两个依然是人类
这就说明了当加入type:human只是加入了p1中的一个新的属性,并没有改到Person类中。此时p2中依然没有type,所以结果依旧为人类。
print(p1.type)并不会修改类属性,而是给实例对象添加一个新的对象属性
如何修改类属性?
加入语句 Person .type = ‘monkey’,修改类属性
在打印 print(p2.type)
整理代码内容为:
class Person(object):
type = ‘人类’
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
p1.type = ‘human’
print(p1.type)
Person .type = ‘monkey’
print(p2.type)
运行结果为:
p2中没有 type 属性,就会上升到 Person 中寻找,已经做了修改为 monkey 的操作,所以此时结果为 monkey。
如图解析:
再加入语句打印出 p1,print(p1.type)
整理代码内容为:
class Person(object):
type = ‘人类’
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Preson(‘张三’,18)
p2 = Preson(‘李四’,19)
p1.type = ‘human’
print(p1.type)
print(p2.type)
print(p1.type)
运行结果为:
由于 p1具有 type 属性,就不会再找 Person 类中的 type 属性,所以这个结果是 human