一.类命名空间与对象的命名空间:
创建一个类就是创建一个命名空间,用来存储定义的所有名字,这些名字称为类的属性.
而类有两种属性:静态属性和动态属性
静态属性就是直接在类中定义的变量
动态属性就是定义在类中的方法
其中类是数据属性是共享给所有对象的
而类的动态属性是绑定到所有对象的,如下图:
解释:首先程序读到Person类,直接创建个Person类空间,开始向下读,将类体里面的静态变量和方法名即函数的内存地址(注意不是方法里面的内容)放在了类的空间里当遇到等号的时候,先执行等号右边的代码,发现是类名+(),就是实例化了个p1对象,在内存中再开辟个实例化P1的空间.这个时候就产生了一个含有类对象指针(指向类对象空间)的空间,接着自动执行__init__方法,将__init__(叫构造方法)里的内容放到p1的空间中.如果我们想用p1.animal 找animal会先从p1空间中找,如果没有,会通过指示牌去类名空间中找
总结查询顺序:
对象,属性:先从对象空间找,如果找不到再从类空间找,再找不到从父类找
类名,属性:先从类空间找,如果找不到就从父类找 即,如果想用类名去找对象的属性是找不到的
ps:对象与对象之间是相互独立的
通过类名可以更改类中的静态变量名
通过对象不能更改类中的静态变量名,只能查询
#计算一个类,实例化多少个对象 class Count: count = 0 def __init__(self): Count.count = Count.count +1 obj1 = Count() obj2 = Count() obj3 = Count() obj4 = Count() print(Count.count) #结果:4
二.组合
定义:给一个类的对象封装一个属性,这个属性是另一个类的对象
class GameRole: def __init__(self,name,ad,hp): self.name = name self.ad = ad self.hp = hp def attack(self,p): p.hp = p.hp - self.ad print('%s攻击%s,%s掉了%s血,还剩%s血'% (self.name,p.name,p.name,self.ad,p.hp)) def armament_weapon(self,wea): self.wea = wea #封装了个属性 class Weapon: def __init__(self,name,ad): self.name = self.name self.ad = ad def fight(self,p1,p2): p2.hp = p2.hp-self.ad print('%s用%s打了%s,%s掉了%s血,还剩%s血' % (p1.name,self.name,p2.name,p2.name,self.ad,p2.hp)) p1 = GameRole('德玛',20,500) p2 = GameRole('剑豪',50,200) axe = Weapon('三板斧',50) broadsword = Weapon('屠龙宝刀',100) p1.armament_weapon(axe) #把三板斧装备到德玛身上 p1.wea.fight(p1,p2) #就相当于axe.fight(p1,p2)