类和对象
在现实生活中是先有对象,再去发现对象的共有特征,归类。
在程序设计中先设计好类,再去实例化一个对象。
在python中,用变量表示特征,用函数表示技能,因而类是变量与函数的结合体,对象是变量与方法(指向类的函数)的结合体
声明一个类
大前提:
1.只有在python2中才分新式类和经典类,python3中统一都是新式类
2.新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类
3.所有类甭管是否显式声明父类,都有一个默认继承object父类
在python2中的区分
经典类:
class 类名:
pass
经典类:
class 类名(父类):
pass
在python3中,上述两种定义方式全都是新式类
类的作用
属性引用和实例化
# 声明类
class Student:
country = "china"
def __init__(self,ID,NAME,GENDER,PROVINCE):
self.id = ID
self.name = NAME
self.gender = GENDER
self.province = PROVINCE
self.country = "England"
def search_score(self):
print("tell score")
def study(self):
print("study",self)
# 类的用法,实例化和属性引用
s1 = Student(421023,"zou","male","hubei") # 实例化
print(Student.country) # china 引用类的属性,该属性与所有对象/实例共享
print(Student.study) # <function Student.study at 0x01276228> 引用类的函数属性,该属性也共享
Student.x = 132 # 新增属性
del Student.x # 删除属性
类属性补充
# 类的特殊用法
print(Student.__name__) # Student 类的名字(字符串)
print(Student.__doc__) # None 类的文档字符串
print(Student.__base__) # <class 'object'> 类的第一个父类(在讲继承时会讲)
print(Student.__bases__) # (<class 'object'>,)类所有父类构成的元组(在讲继承时会讲)
print(Student.__dict__) # 类的字典属性 {'country': 'china', 'search_score': <function Student.search_score at 0x01B46228>,
# '__doc__': None,
print(Student.__module__) # __main__ 类定义所在的模块
print(Student.__class__) # <class 'type'> 实例对应的类(仅新式类中)
对象的用法
对象只有一个用法就是属性引用
对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法,绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样
# 对象只有一个用法 :属性引用
print(s1.country) # china
# 对象的绑定方法,绑定方法的核心在于"绑定",唯一绑定一个确定的对象,谁来调用就作用于谁
print(Student.study,id(Student.study)) # <function Student.study at 0x015C6228> 22831656 内存地址不同
print(s1.study,id(s1.study)) # <bound method Student.study of <__main__.Student object at 0x015CCE50>> 22174976
查看对象和类的名称空间
类名.dict:查出的是一个字典,key为属性名,value为属性值
print(s1.__dict__) # 对象的字典属性----{'gender': 'male', 'id': 421023, 'province': 'hubei', 'name': 'zou'}
print(Student.__dict__) # 类的字典属性----{'__doc__': None, 'country': 'china',
# '__weakref__': <attribute '__weakref__' of 'Student' objects>,
# '__dict__': <attribute '__dict__' of 'Student' objects>,
# '__module__': '__main__', '__init__': <function Student.__init__ at 0x01F06DF8>,
# 'search_score': <function Student.search_score at 0x01F06228>,
# 'study': <function Student.study at 0x01F06E40>}
对象之间的交互
基于面向对象设的游戏:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能。一个英雄可以攻击另外一个英雄,这就是对象之间的交互
交互:锐雯雯攻击草丛伦,反之一样
# 对象之间的交互
class Garen:
def __init__(self,nickname,aggressivity=54,life_value=414):
self.nickname = nickname
self.life_value = life_value
self.aggressivity = aggressivity
def attack(self,obj):
obj.life_value -= self.aggressivity
class Riven:
camp = '诺克萨斯' # (锐雯)的阵营都是Noxus;
def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力和生命值
self.nickname = nickname # 为自己的锐雯起个别名
self.life_value = life_value # 英雄都有自己的生命值;
self.aggressivity = aggressivity # 英雄都有自己的攻击力;
def attack(self,obj): # 普通攻击技能,obj是敌人;
obj.life_value -= self.aggressivity # 根据自己的攻击力,攻击敌人就减掉敌人的生命值。
r1 = Riven("瑞雯")
# print(r1.nickname)
g1 = Garen("盖伦")
print("from Riven",r1.life_value) # from Riven 414
g1.attack(r1)
print(r1.life_value) # 360
print("from Garen",g1.life_value) # from Garen 414
r1.attack(g1)
r1.attack(g1)
print("from Garen",g1.life_value) # from Garen 306
类名称空间与对象/实例名称空间
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
模拟对象交互
# 对象交互,模拟英雄联盟盖伦和瑞文的攻击
class Garen:
camp = '德玛西亚'
def __init__(self,nickname,aggressivity=54,life_value=414,money = 500):
self.nickname = nickname
self.life_value = life_value
self.aggressivity = aggressivity
self.money = money
def attack(self,obj):
obj.life_value -= self.aggressivity
class Riven:
camp = '诺克萨斯'
def __init__(self,nickname,aggressivity=54,life_value=414,money = 500):
self.nickname = nickname
self.life_value = life_value
self.aggressivity = aggressivity
self.money = money
def attack(self,obj):
obj.life_value -= self.aggressivity
class Weapon:
def __init__(self,add_life_value=80, add_aggressivity=10,price=450 ):
self.add_life_value = add_life_value
self.add_aggressivity = add_aggressivity
self.price = price
def update(self,obj):
obj.life_value += self.add_life_value # 加生命值
obj.aggressivity += self.add_aggressivity # 加攻击
obj.money -= self.price # 减钱
def dazhao(self,obj): # 这是该装备的主动技能,喷火,烧死对方
obj.life_value -= 100 # 假设大招的攻击力是100
g1 = Garen("盖伦")
r1 = Riven("瑞文")
w1 = Weapon()
print(g1.life_value,g1.aggressivity,g1.money) # g1的攻击力,生命值,护甲
# g1.life_value=414 g1.aggressivity = 54 g1.money = 500
if g1.money > w1.price:
g1.w1 = w1
w1.update(g1)
print(g1.life_value,g1.aggressivity,g1.money) # 穿上装备后,r1的攻击力,生命值,护甲
# g1.life_value=494 g1.aggressivity = 64 g1.money = 50
print(r1.life_value) # life_value = 414
g1.attack(r1) # 普通攻击
g1.w1.dazhao(r1) # 用装备攻击
print(r1.life_value) #g1的生命值小于0就死了 life_value = 250