day22.继承及魔术方法__init__
一、单继承
""" 如果一个类继承另外一个类, 该类叫做子类(衍生类),被继承的类叫做父类(基类,超类) 继承: (1) 单继承 (2) 多继承 python中,所有的类都默认继承父类object """
class Human(object): hair = "黑色" sex = "男" def cry(self): print("人类在伤心的时候,会留下鳄鱼的眼泪") def eat(self): print("人类在远古时候,抓到猎物直接吃") def __makebaby(self): print("人类在发育到成熟的时候,会造人")
1、子父继承之后,子类可以调用父类的公有成员
class Man(Human): pass obj = Man() print(obj.hair) obj.cry()
2、子父继承之后,子类不能调用父类的私有成员
class Woman(Human): def pub_func(self): self.__makebaby() obj = Woman() # obj.__makebaby() error # obj.pub_func() error
3、子父继承之后,子类可以改写父类中的方法
""" 子父继承之后 如果子类里面有该成员属性或者方法,优先调用自己的 如果没有该成员,调用父类中的成员 如果都没有,直接报错 """
class Children(Human): sex = "女性" def cry(self): print("小孩只会哇哇哇的哭") obj = Children() obj.cry() print(obj.__dict__) print(Children.__dict__)
二、多继承
1、基本语法
class Father(): property = "风流倜傥,一表人才,一枝梨花压海棠" def f_hobby(self): print("社会摇,蹦迪,吃喝嫖赌,大保健") class Mother(): property = "闭月羞花,倾国倾城,一枝红杏出墙来" def m_hobby(self): print("打麻将,打牌,喝酒抽烟烫头,跳广场舞") class Daughter(Father,Mother): pass # 实例化对象 obj = Daughter() print(obj.property) obj.m_hobby()
2、super用法
""" (1)super本身是一个类 super()是一个对象 用于调用父类的绑定方法 (2)super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self) (3)super用途: 解决复杂的多继承调用顺序 """
class Father(): property = "风流倜傥,一表人才,一枝梨花压海棠" def f_hobby(): print("社会摇,蹦迪,吃喝嫖赌,大保健") class Mother(): property = "闭月羞花,倾国倾城,一枝红杏出墙来" def m_hobby(self): print("打麻将,打牌,喝酒抽烟烫头,跳广场舞") class Son(Father,Mother): property = "喜欢打游戏,wow,lol,dnf,泡泡堂,cf,dota,大话西游,跑跑卡丁车,吃鸡" # 1.利用类来调用父类的成员 def skill1(self): Father.f_hobby() print(Mother.property) # 2.利用对象调用父类的成员 def skill2(self): self.m_hobby() print(self.property) # 3.利用super调用父类的属性和方法 """ super()只调用父类的相关公有成员,不会调用自己的本类成员,父类没有直接报错. super()在调用父类方法时,只调用父类的绑定方法,默认传递参数是本类的对象self """ def skill3(self): # print(super()) print(super().property) super().m_hobby() # super().f_hobby() error obj = Son() print("<===============>") obj.skill1() print("<===============>") obj.skill2() print("<===============>") obj.skill3()
""" self 和 super()的区别 self 在调用成员时,先看看自己的类对象中是否存在该成员,如果有调用自己的,如果没有,调用父类的.如果都没有报错 super() 在调用成员时,只调用父类的相关成员(属性,绑定方法),永远不会调用自己的.如果父类没有,直接报错. """
三、菱形继承
""" Human Man Woman Children """
class OldWoman(): pass class Human(): pty = 4 def feelT(self): print("原始人类如果热了,脱皮1") print(self.pty) print("原始人类如果冷了,扒别人的皮2") class Man(Human): # pty = 3 def feelT(self): print("现代男人如果热了,脱衣服,脱裤子3") super().feelT() print("现代男人如果冷了,脱别人的衣服,脱别人的裤子4") class Woman(Human): # pty = 2 def feelT(self): print("现代女人如果热了,吹空调,吃雪糕5") super().feelT() print("现代女人如果冷了,喝热水,用暖宝宝6") class Children(Man,Woman): # pty = 1 def feelT(self): print("现代小孩如果热了,就哭,嗯哭7") super().feelT() print("现代小孩如果冷了,也要哭8") obj = Children() obj.feelT()
1、mro列表
# super用途的一个体现.解决复杂的多继承调用顺序关系 # 类.mro() 返回的是方法调用顺序列表,针对于多继承下的同名方法,按照顺序依次的进行调用
lst = Children.mro() print(lst) """ [ <class '__main__.Children'>, <class '__main__.Man'>, <class '__main__.Woman'>, <class '__main__.Human'>, <class 'object'> ] """
2、issubclass 判断子父关系 (应用在类当中,判断子父关系)
"""只要在一条继承链上即可(有血缘关系)""" res = issubclass(Children,Man) print(res) res = issubclass(Children,Woman) print(res) res = issubclass(Children,Human) print(res) res = issubclass(Children,(Human,Woman,Man,OldWoman)) print(res) res = issubclass(Children,OldWoman) print(res)
3、isinstance (应用在对象和类之间,判断类型)
"""只要在一条继承链上即可(有血缘关系)""" res = isinstance(obj,Children) print(res) res = isinstance(obj,Human) print(res) res = isinstance(obj,(Human,Children,Woman)) print(res) res = isinstance(obj,OldWoman) print(res)
四、魔术方法 __init__(self)
''' 触发时机:实例化对象,初始化的时候触发 功能:为对象添加成员 参数:参数不固定,至少一个self参数 返回值:无 '''
1、基本语法
class MyClass(): def __init__(self): print("初始化方法被触发") # 为当前对象self 添加成员 name self.name = "袁伟倬"
# 实例化对象 obj = MyClass() print(obj.name)
2、带有多个参数的构造方法
class MyClass(): def __init__(self,name): # self.成员名 = 参数 self.name = name # 实例化对象 obj = MyClass("kxq") # 在实例化对象时候,给构造方法传递参数 print(obj.name)
3、类可以是一个,对象可以是多个
"""一个类可以实例化多个不同的对象,而对象和对象之间彼此独立,但都可以使用类中的公有的成员""" class Children(): def __init__(self,name,skin): self.name = name self.skin = skin def cry(self): print("小孩一出生就哇哇哇的哭") def drink(self): print("小孩一下生就要喝奶奶") def __la(self): print("小孩拉粑粑是私有的") def pub_info(self): print("该对象的名字是{},该对象的肤色是{}".format(self.name,self.skin)) # 创建第一个小孩 afanda = Children("阿凡达","蓝色的") afanda.pub_info() afanda.cry() # 创建第二个小孩 afanti = Children("阿凡提","黄色的") afanti.pub_info() afanti.drink() # 创建第三个小孩 bao = Children("我滴宝强","绿色的") bao.pub_info() # bao.__la() # 无法在类外调用私有的成员
五、练习
# ### 1.完成下列功能: # 1.1创建一个人类Person,再类中创建3个成员属性 # animal = '高级动物' # soul = '有灵魂' # language = '语言' # 1.2在类中定义三个方法,吃饭,睡觉,工作. # 1.3在此类中的__init__方法中,给对象封装5个属性: 国家 , 姓名 , 性别 , 年龄 , 身高. # 1.4实例化四个人类对象: # 第一个人类对象p1属性为:中国,alex,未知,42,175. # 第二个人类对象p2属性为:美国,武大,男,35,160. # 第三个人类对象p3属性为:你自己定义. # 第四个人类对象p4属性为:p1的国籍,p2的名字,p3的性别,p2的年龄,p3的身高. # 1.5 通过p1对象执行吃饭方法,方法里面打印:alex在吃饭. # 1.6 通过p2对象执行吃饭方法,方法里面打印:武大在吃饭. # 1.7 通过p3对象执行吃饭方法,方法里面打印:(p3对象自己的名字)在吃饭. # 1.8 通过p1对象找到类中成员属性animal # 1.9 通过p2对象找到类中成员属性soul # 2.0 通过p3对象找到类中成员属性language
class Person(): animal = '高级动物' soul = '有灵魂' language = '语言' def __init__(self,country,name,sex,age,height): self.country = country self.name = name self.sex = sex self.age = age self.height = height def eat(self): print("{}在吃饭".format(self.name)) def sleep(): pass def work(): pass p1 = Person("中国","alex","未知",42,175) p2 = Person("美国","武大","男",35,160) p3 = Person("中文","宋云杰","男",18,130) p4 = Person(p1.country,p2.name,p3.sex,p2.age,p3.height) p1.eat() p2.eat() p3.eat() print(p1.animal) print(p2.soul) print(p3.language)
# ### 2.通过自己创建类,实例化对象 #通过调用对象当中的方法,在终端输出如下信息 #小明,10岁,男,上山去砍柴 #小明,10岁,男,开车去东北 #小明,10岁,男,最爱大保健 #老李,90岁,男,上山去砍柴 #老李,90岁,男,开车去东北 #老李,90岁,男,最爱大保健
class MyClass(): def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def print_func(self): strvar = """ {who},{age},{sex},上山去砍柴 {who},{age},{sex},开车去东北 {who},{age},{sex},最爱大保健 """ print(strvar.format(who=self.name,age=self.age,sex=self.sex)) obj = MyClass("小明","10岁","男") obj.print_func()
# ### 3.模拟英雄联盟写一个游戏人物的类 #要求: #(1) 创建一个 Game_role 的类. #(2) 构造方法中给对象封装 name,ad(攻击力),hp(血量).三个属性. #(3) 创建一个attack方法,此方法是实例化两个对象,互相攻击的功能: #例: 实例化一个对象 盖伦,ad为10, hp为100 #实例化另个一个对象 剑豪 ad为20, hp为80 #盖伦通过attack方法攻击剑豪,此方法要完成 '谁攻击谁,谁掉了多少血, 还剩多少血'的提示功能.
class Game_role(): def __init__(self,name,ad,hp): self.name = name self.ad = ad self.hp = hp def attack(self,obj): print('{}攻击{},{}掉了{}血, 还剩{}血'.format(self.name,obj.name,obj.name,self.ad,obj.hp-self.ad)) gailun = Game_role("盖伦",10,100) jianhao = Game_role("剑豪",20,80) gailun.attack(jianhao) # self -> gailun obj -> jianhao
# ### 4.请定义一个圆形类,有计算周长和面积的两个方法 (圆的半径通过参数传递给初始化方法)
import math class Circle(): def __init__(self,r): self.r = r def zhouchang(self): return 2 * math.pi * self.r def mianji(self): return math.pi * pow(self.r,2) obj = Circle(10) print(obj.zhouchang()) print(obj.mianji())
# ### 5创建AB两个类,A类中有属性abc=5把A类的对象存储在B类对象的成员属性pty中,用B类对象调用出abc这个值.
class A(): abc = 5 class B(): def __init__(self,obj): self.pty = obj obj1 = A() obj2 = B(obj1) print(obj2.pty) print(obj2.pty.abc)
简答题:
# 1.类或对象是否能做字典的key 可以~ # 2.简述python的私有成员是如何实现的 改名策略[_类+私有成员名] # 3.私有成员能在类的外部使用么?能在子类中使用么?不行 不行
读程序写结果
# # 1.读程序写结果.(不执行) class StarkConfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) class RoleConfig(StarkConfig): def changelist(self,request): print('666') # 创建了一个列表,列表中有三个对象(实例) config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)] for item in config_obj_list: print(item.num) # 1 2 3 print("<====================>") # 2.读程序写结果.(不执行) class StarkConfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) class RoleConfig(StarkConfig): pass # 创建了一个列表,列表中有三个对象(实例) config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)] for item in config_obj_list: item.changelist(168) # 1 168 2 168 3 168 print(config_obj_list[0].num) # 1 # 3.读程序写结果.(不执行) print("<====================>") class StarkConfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) class RoleConfig(StarkConfig): def changelist(self,request): print(666,self.num) config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)] for item in config_obj_list: item.changelist(168) # 1,168 | 2,168 | 666,3 # 4.读程序写结果.(不执行) print("<====================>") class StarkConfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self,request): print(666,self.num) config_obj_list = [StarkConfig(1),StarkConfig(2),RoleConfig(3)] config_obj_list[1].run() #2 999 config_obj_list[2].run() #666 3 # 5.读程序写结果.(不执行) print("<====================>") class StarkConfig(object): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self,request): print(666,self.num) class AdminSite(object): def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v site = AdminSite() print(len(site._registry)) # 0 site.register('range',666) # self._registry[range] = 666 site.register('shilei',438) # self._registry[shilei] = 438 print(len(site._registry)) # 2 site.register('lyd',StarkConfig(19))# self._registry[lyd] = StarkConfig(19) site.register('yjl',StarkConfig(20))# self._registry[yjl] = StarkConfig(20) site.register('fgz',RoleConfig(33)) # self._registry[fgz] = RoleConfig(33) print(len(site._registry)) # 5 print(site._registry) # 6.读程序写结果.(不执行) print("<====================>") class StarkConfig(): def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self,request): # request = 5 print(666,self.num,request) class AdminSite(): def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v site = AdminSite() site.register('lyd',StarkConfig(19)) site.register('yjl',StarkConfig(20)) site.register('fgz',RoleConfig(33)) # num 33 for k,row in site._registry.items(): row.changelist(5) # 19 5 | 20 5 | 666 33 5 for k,row in site._registry.items(): row.run() # 19 , 999 | 20 , 999 | 666 33 999 # 7.读程序写结果.(不执行) """ 在类中为当前对象添加了私有成员. """ print("<====================>") class JustCounter: __secretCount = 0 def count(self): print(self.__secretCount) # 1.获取类当中的私有成员 0 | 2. 获取的是对象中的私有成员 1 self.__secretCount += 1 # self.__secretCount = self.__secretCount + 1 = 0 + 1 = 1 # 给对象中的私有成员赋值 def count3(): print(JustCounter.__secretCount) # 0 # JustCounter.__secretCount = JustCounter.__secretCount + 1 = 0 + 1 = 1 JustCounter.__secretCount += 1 print(JustCounter.__secretCount) # 1 class Bars(JustCounter): def count2(self): print(self.__secretCount) """ # 情况一 counter1 = JustCounter() counter1.count() # 0 counter1.count() # 1 JustCounter.count3() # 0 1 # 情况二 counter2 = Bars() counter2.count() # 0 counter2.count() # 1 # 情况三 # JustCounter.count3() # 0 1 """
# ### 小人射击 """面向对象的核心思想: 把对象当做程序中的一个最小单元,让对象操作一切""" """ 弹夹: 属性: 子弹数量 bulletcount 方法: 无 枪 : 属性: 弹夹 方法: 射击 shoot 人 : 属性: 枪 方法: (1) 射击 (2) 换子弹 """ from package.bulletbox import BulletBox from package.gun import Gun from package.person import Person # 先创建弹夹 danjia = BulletBox(20) # 在创建一杆枪 ak47 = Gun(danjia) # 在创造一个人 songyunjie = Person(ak47,"宋云杰") # 小人射击 if __name__ == "__main__": # 射击 songyunjie.fire(15) # 填充 songyunjie.fillcount(10) # 在射击 songyunjie.fire(150)
# ### 弹夹类 class BulletBox(): def __init__(self,bulletcount): self.bulletcount = bulletcount
# ### 枪类 class Gun(): def __init__(self,bulletbox): # 存放的是弹夹对象 self.bulletbox = bulletbox def shoot(self,shootcount): if self.bulletbox.bulletcount < shootcount: print("对不起,请先填充子弹~") else: # 剩余的子弹 = 总的子弹数量 - 射击的数量 self.bulletbox.bulletcount -= shootcount print("突" * shootcount , "你射出了{}发,还剩下{}发".format(shootcount,self.bulletbox.bulletcount))
# ### 人类 class Person(): def __init__(self,gun,name): self.gun = gun self.name = "宋云杰" # 填充子弹 def fillcount(self,fillnum): # 往弹夹里面赛子弹 # self.枪对象 -> 弹夹对象 -> 弹夹数量属性 self.gun.bulletbox.bulletcount += fillnum # 射击 def fire(self,num): print("{}此刻正在野外射击~".format(self.name)) # 枪对象.shoot self.gun.shoot(num)