Three---面向对象与面向过程/属性和变量/关于self/一些魔法方法的使用/继承 ...

王柳  金牌会员 | 2022-9-16 17:18:32 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 909|帖子 909|积分 2727

python的面向对象

面向对象与面向过程

面向过程


  • 面向过程思想:需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做)
面向对象


  • 面向对象的三大特征:封装性、继承性、多态性
  • 面向对象思想:需要实现一个功能的时候,看重的并不是过程和步骤,而是关心谁帮我做这件事(偷懒,找人帮我做)
类与对象


  • 对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另一个新的概念——类
  • 类:抽象的,是一张“手机设计图”
  • 对象:具体的,是一个“真正的手机实例”
  • 类是抽象的,在使用的时候通常会找到这个类的一个具体的存在;一个类可以找到多个对象
  1. #学生案例
  2. class Student():   #创建一个学生类
  3.     #定义一个info函数,并传参至self本身
  4.     def info(self,name,age,sex):   
  5.         print('学生的姓名是:',self.name)
  6.         print('学生的年龄是:',self.age)
  7.         print('学生的性别是:',self.sex)
  8. yinianji = Student()   #创建一个具体的对象:一年级
  9. yinianji.info()   #实例化对象调用定义的info函数
复制代码
案例

当创建一个对象时,就是用一个模子来制造一个实物
  1. #案例
  2. class Dog():   #定义一个类的形式
  3.     #info是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self
  4.     def info(self):
  5.    
  6.     #当对象调用实例化方法时,python会自动将对象本身的引用作为参数,传递到实例方法的第一个参数self里面
  7.         print(self)
  8.         print("狗祖宗")
  9. #Dog这个类实例化了一个对象 jinmao
  10. jinmao = Dog()
  11. #对象调用实例化方法info(),执行info()中封装的代码 .表示选择属性或方法
  12. jinmao.info()
  13. #打印对象,则默认打印对象在内存中的地址,结果等同于info中的print(self)
  14. print(jinmao)
  15. #id(taidamier)则时内存地址的十进制形式表示
  16. print(id(jinmao))
  17. -----------------------------------------------------------
  18. <__main__.Dog object at 0x00000190A9DC67F0>
  19. 狗祖宗
  20. <__main__.Dog object at 0x00000190A9DC67F0>
  21. 1720836712432
复制代码
属性和变量

属性和变量的区别


  • 属性:指某个对象的具体特性
  • 变量:指可以更改的量
属性和变量的判断依据


  • 根据宿主判断:变量无宿主,属性有宿主
  • 根据宿主的不同又分为对象属性以及类属性
对象属性获取


  • 对象既然有实例方法,也可以有自己的属性
  • 在方法内通过self获取对象属性
  1. #对象属性获取
  2. class Dog():   #定义一个狗类
  3.     def move(self):    #移动实例方法
  4.         print("moving...")
  5.     def attack(self):   #咬人实例方法
  6.         print("咬人")
  7. #实例化一个狗对象 jinmao
  8. jinmao = Dog()
  9. #给对象添加属性,以及对应的属性值
  10. jinmao.name = "xiao"
  11. jinmao.hp = 200
  12. jinmao.atk = 40
  13. jinmao.armor = 100
  14. #通过.成员选择运算符,获取对象的属性值
  15. print("%s 的生命值为:%d" %(jinmao.name,jinmao.hp))
  16. print("%s 的攻击力为:%d" %(jinmao.name,jinmao.atk))
  17. print("%s 的护甲值为:%d" %(jinmao.name,jinmao.armor))
  18. #通过.成员选择运算符,获取对象的实例方法
  19. jinmao.move()
  20. jinmao.attack()
  21. -----------------------------------------------------------
  22. xiao 的生命值为:200
  23. xiao 的攻击力为:40
  24. xiao 的护甲值为:100
  25. moving...
  26. 咬人
复制代码
关于self


  • self就是实例化对象本身
  1. #关于self
  2. class A:
  3.     def f(self,data):
  4.         print(self.name)
  5.         print(data)
  6. o = A()
  7. print(A.f)
  8. print(o.f)
  9. -----------------------------------------------------------
  10. <function A.f at 0x000002725D28ADC0>
  11. <bound method A.f of <__main__.A object at 0x000002725D2467F0>>
复制代码

  • 其中A.f对应的时function 即为一个普通的函数
  • o.f为bound method 即在函数上绑定了一个对象 —— o
  • 结论:o.f 是返回了一个method object ,而当去调用这个object时,他会记住被创建时绑定的对象,即返回该对象,默认参数为self
魔法方法

魔法方法__init__()

__init__方法可以在创建对象时就拥有一些属性,__init__通常用来做属性初始化 或 赋值 操作


  • 如果类没有写__init__方法,python会自动创建,但不会执行任何操作
  • 所以一个类里无论自己是否编写__init__方法 都一定有__init__方法
案例一
  1. #init方法
  2. class Dog():
  3. #方法,用来做变量初始化 或 赋值 操作,在类实例化对象的时候,会被自动调用
  4.     def __init__(self,name,hp) -> None:
  5.         #__init__方法也可以带参数
  6.         self.name = name
  7.         self.hp = hp
  8.         print(self.name,self.hp)
  9. #实例化一个对象,并自动调用__init__方法
  10. xiaohuang = Dog("小黄",200)
  11. ---------------------------------------------------------
  12. class Dog():
  13.     def f(self,name,hp):
  14.         self.name = name
  15.         self.hp = hp
  16.         print(self.name,self.hp)
  17.         
  18. xiaohuang = Dog()
  19. xiaohuang.f("小黄",200)
复制代码
案例二
  1. #init方法二
  2. class Dog():
  3.    
  4.     def __init__(self,name,skill,hp) -> None:
  5.         
  6.         self.name = name
  7.         self.skill = skill
  8.         self.hp = hp
  9.         
  10.     def move(self):
  11.         print("%s 正在前往事发地点..." % self.name)
  12.     def attack(self):
  13.         print("%s 咬人 %s..."%(self.name,self.skill))
  14.     def info(self):
  15.         print("%s 的生命值:%d"%(self.name,self.hp))
  16. #实例化对象时,参数会传递到对象的__init__()方法中
  17. jinmao = Dog("金毛","连环咬",200)
  18. hashiqi = Dog("哈士奇","不松口",300)
  19. #直接输出对象即为地址
  20. print(jinmao)
  21. print(hashiqi)
  22. #不同对象的属性值的单独保存
  23. print(id(jinmao.name))
  24. print(id(hashiqi.name))
  25. #同一个类的不同对象,实例方法共享
  26. print(id(jinmao.attack))
  27. print(id(hashiqi.attack))
  28. -----------------------------------------------------------
  29. <__main__.Dog object at 0x000001A3209367F0>
  30. <__main__.Dog object at 0x000001A32089F250>
  31. 1800138028976
  32. 1800138029168
  33. 1800131850880
  34. 1800131850880
复制代码
总结


  • 在类内部获取 属性 和 实例方法,通过self获取
  • 在类外部获取 属性 和 实例方法,通过对象名获取
  • 如果有一个类有多个对象,每个对象的属性时各自保存的,都有各自独立的地址
  • 实例方法时所有对象共享的,只占用一份内存空间
  • 类会通过self来判断是哪个对象,调用了实例方法
魔法方法__str__()

该方法用来显示信息,通过一个字符串来描述实例对象,该方法需要return一个数据,并且只有self一个参数,在类的外部时用print(对象)打印这个数据(面向用户)
  1. #str方法
  2. class Person():
  3.     def __init__(self,name,age):
  4.         self.name = name
  5.         self.age = age
  6.     def __str__(self):
  7.         return "此人姓名为%s,此人的年龄为%s"%(self.name,self.age)
  8. p1 = Person("李四",18)
  9. P2 = Person("王五",19)
  10. print(p1)
  11. print(P2)
  12. -------------------------------------------------------------
  13. 此人姓名为李四,此人的年龄为18
  14. 此人姓名为王五,此人的年龄为19
复制代码
  1. 触发方式:
  2. 1、直接通过print函数去打印
  3. 2、通过出发str函数进行转换
复制代码
魔法方法__repr__()

通过一个字符串描述实例对象的信息(面向开发人员)
  1. #repr方法
  2. class Person():
  3.     def __init__(self,name,age):
  4.         self.name = name
  5.         self.age = age
  6.     def __str__(self):
  7.         return "此人姓名为%s,此人的年龄为%s"%(self.name,self.age)
  8. p1 = Person("李四",18)
  9. P2 = Person("王五",19)
  10. print(repr(p1))
  11. print(P2)
  12. -------------------------------------------------------------
  13. <__main__.Person object at 0x000001E7D9FD67F0>
  14. 此人姓名为王五,此人的年龄为19
复制代码
  1. #修改repr值
  2. class Person():
  3.     def __init__(self,name,age):
  4.         self.name = name
  5.         self.age = age
  6.     def __str__(self):
  7.         return "此人姓名为%s,此人的年龄为%s"%(self.name,self.age)
  8.     def __repr__(self):   #更改repr参数值
  9.         return "self"
  10. p1 = Person("李四",18)
  11. P2 = Person("王五",19)
  12. print(repr(p1))
  13. print(repr(P2))
  14. print(P2)
  15. -------------------------------------------------------------
  16. self
  17. self
  18. 此人姓名为王五,此人的年龄为19
复制代码
repr与str

在输出值时当存在str方法便会优先输出str,repr可以面向开发者,同样repr方法也可以作为一种方法去输出str
  1. #repr与str
  2. import datetime
  3. t = datetime.datetime.now()
  4. print(t)   #此处输出的为datetime库中的类对应的str字符串
  5. print(repr(t))   #同时输出repr进行对比
  6. -------------------------------------------------------------
  7. 2022-07-15 23:53:55.418332   #此为对应字符串输出值
  8. datetime.datetime(2022, 7, 15, 23, 53, 55, 418332)   #此为repr值
复制代码
  1. #通过eval函数输出repr
  2. import datetime
  3. t = datetime.datetime.now()
  4. print(t)   #此处输出的为datetime库中的类对应的str字符串
  5. tmp = repr(t)
  6. result = eval(tmp)   #使用eval函数执行输出repr值的t
  7. print(result)
  8. -------------------------------------------------------------
  9. 2022-07-16 00:00:31.144619
  10. 2022-07-16 00:00:31.144619
复制代码
魔法方法__del__()

创建对象后,python解释器默认调用__init__()方法
当删除一个对象时,python解释器也会默认调用一个方法,这个方法叫__del__()
  1. #del方法
  2. class Dog():
  3.     #创建对象后__init__方法会自动被调用
  4.     def __init__(self, name):
  5.         print("__init__方法被调用",name+"出生了")
  6.         self.name = name
  7.     #当对象执行完毕被删除时,__del__方法会自动被调用
  8.     def __del__(self):
  9.         print("__del__方法被调用%s死了"%(self.name))
  10. jinmao = Dog("金毛")
  11. ---------------------------------------------------------
  12. __init__方法被调用 金毛出生了
  13. __del__方法被调用金毛死了
复制代码
继承


  • 子类可以重写父类的属性和方法后,依然可以调用父类的属性和方法
  • 使用super方法调用父类
  • 多层继承关系同样可以实现
  • 装饰器
  1. class Dog():   #创建父类Dog
  2.    
  3.     def __init__(self) -> None:
  4.         self.name = "dog dad"
  5.     def skill_dad1(self):
  6.         print("attack people")
  7. class Dog2():   #创建父类Dog2
  8.     def __init__(self) -> None:
  9.         self.name = "dog mom"
  10.     def skill_mom1(self):
  11.         print("attack dog")
  12.     def skill_mom2(self):
  13.         print("摇尾巴")
  14. class Son(Dog,Dog2):   
  15. #创建子类Son并继承父类Dog和Dog2,继承时优先继承第一个父类Dog
  16.     def __init__(self) -> None:
  17.         self.name = "dog son"
  18.     def skill(self):
  19.         print("lick people")
  20.     def dad_skill(self):   
  21.         #通过super方法进行调用父类所定义的函数与方法
  22.         super().__init__()   
  23.         super().skill_dad1()
  24.     def mom_skill(self):
  25.         super().__init__()
  26.         super().skill_mom1()
  27.         super().skill_mom2()
  28.    
  29. jinmao = Son()
  30. jinmao.dad_skill()
  31. jinmao.mom_skill()
  32. --------------------------------------------------------------
  33. attack people
  34. attack dog
  35. 摇尾巴
复制代码
多态


  • 不同的子对象调用相同的父类放啊,产生不同的结果(继承+重写)
  • 一个父类可以拥有多个子类继承
  1. #多态
  2. class Dog():
  3.     def __init__(self) -> None:
  4.         self.name = "dog mom"
  5.     def skill(self):
  6.         print("attack dog")
  7. #子类/派生类
  8. class Son1(Dog):
  9.     def skill(self):
  10.         print("attack man")
  11. class Son2(Dog):
  12.     def skill(self):
  13.         print("attack woman")
  14. class Son3(Dog):
  15.     def skill(self):
  16.         print("attack child")
  17. #实例化
  18. son1 = Son1().skill()
  19. son2 = Son2().skill()
  20. son3 = Son3().skill()
  21. ---------------------------------------------------------
  22. attack man
  23. attack woman
  24. attack child
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表