一, 类名称空间与对象的名称空间
1. 创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类
的属性.(静态变量,动态变量名及其内存地址)
2. 而类有两种属性:静态属性和动态属性
-
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法
其中类的数据属性是共享给所有对象的
>>>id(egg.role) 4341594072 >>>id(Person.role) 4341594072
而类的动态属性是绑定到所有对象的
>>>egg.attack <bound method Person.attack of <__main__.Person object at 0x101285860>> >>>Person.attack <function Person.attack at 0x10127abf8>
3. 创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象或
实例的属性
运行py文件首先会开辟一个类空间,从上到下执行,把类中静态变量,方法名及其地址记录到类空间中,当
执行到 类名() 时,会产生一个保存着类指针的对象空间,然后自动执行init方法,将空间地址传给self,并把
()中的属性进行传值封装,最后把空间之地址传给对象名.
二, 查询顺序
1. 在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父
类...最后都找不到就抛出异常
2. 在类中找name会先从本类中找,如果找不到则去父类中找,但是不会在对象空间中找
class Person: animal='高级动物' soup='有灵魂' language='语言' def __init__(self,country,name,sex,age,hige,animal): self.country=country self.name=name self.sex=sex self.age=age self.hige=hige self.animal=animal #先从对象空间进行查询,若找不到,则寻找父类.当对象空间中的属性与类相同时,首选对象空间. def foot(self,p): print('%s和%s 在吃饭' % (self.name,p.name)) def sleep(self): print('%s 在睡觉' % self.name) def work(self): pass p1=Person('中国','alex','未知',42,175,'情兽') #对象与对象之间是独立的 p2=Person('美国','李','未知',33,175,'智障') Person.language='汉语' print(Person.language) #通过类名可以更改类中的静态变量,但是通过对象不能改,只能引用 p1.foot(p2) #print(Person.age) #先从本类空间中找,若找不到,找父类.但是不能找对象空间中的属性 print(p1.animal)
三, 组合
1.
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=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('屠龙刀',100) p1.armament_weapon(axe) #给 p1 增加axe属性. 把axe对象空间传给wea. p1.wea.fight(p1,p2) #以人为主体 print(p1.wea.name) print(p1.wea.ad)