新闻详情

新闻详情

首页 / 资讯中心 / 详情

python学习day08——封装装饰器、继承、多态

发布时间:2026/9/27 4:44:56来源:尧图网络
python学习day08——封装装饰器、继承、多态
1.封装装饰器的写法 书写封装代码的时候 关于装饰器的细节 1.通常情况下 我们先写property 然后再写xxx.setter不然的话xxx会找不到报错 2.setter装饰器前边的名字是根据property装饰器对应的函数名命名的 class Test: ​ property def name(self): return get_name ​ name.setter def name(self,name): self.__name name print(name) pass ​ t1Test() ​ print(t1.name) ​ t1.nametest print(t1.name)2.对象的创建过程创建对象obj 类名()对象创建分为2 大阶段分配空间 → 初始化对应两个魔法方法__new__创建、分配内存生成空对象__init__给空对象初始化属性顺序先__new__→ 再__init__分步详解第一步调用__new__(cls, *args, **kwargs)第一个参数cls当前类作用开辟一块内存空间创建并返回一个空的实例对象返回值必须返回创建出来的对象super().__new__(cls)如果__new__没有返回对象那么__init__不会执行__new__是真正造对象的工厂方法。第二步调用__init__(self, *args, **kwargs)self就是__new__返回过来的那个空对象作用给对象添加实例属性做初始化赋值__init__没有返回值只能 return None 对象的创建过程 ​ 创建对象对比 java写法类名 对象名 new 类名() 会通过构造方法创建对象 python写法对象名 类名() ​ Python创建对象的过程 1.访问__new__函数 创建对象 __new__也是魔法函数 每个类默认自带的继承自object 这个函数只负责创建对象最终由祖宗类object来执行因为在Python中只有object有权限访问底层c语言的代码 在堆内存开辟空间 创建对象 此时创建没有任何属性的对象 返回回来 传递给__init__函数 ​ 2.__init__函数接收__new__函数传入的对象 对此对象添加属性 并且赋予用户传入的值 ​ 3.完成对象创建 得到一个有具体属性和属性值的对象 ​ ​ class Person: def __new__(cls, *args, **kwargs): print(__new__函数执行了) return super().__new__(cls) ​ def __init__(self, name, age): print(__init__函数执行了) self.name name self.age age ​ pass ​ p1Person(赵四,20) ​3. 继承概念引入 编写两个类 狗狗类 属性名字 亲密值 健康值 品种 方法介绍狗狗信息 企鹅类 属性名字 亲密值 健康值 性别 方法介绍企鹅信息 ​ 当前模块中编写了两个类 这两类中有相同的属性 和 相似度非常高的方法 这些如果每次都单独写一遍 是非常啰嗦的 冗余的代码 所以 我们应该考虑 只书写一遍 然后重复利用 使用继承优化 class Dog: def __init__(self, name, love, health, strain): self.name name self.love love self.health health self.strain strain ​ def print_info(self): print(f狗狗的名字是{self.name}) print(f狗狗的亲密值是{self.love}) print(f狗狗的健康值是{self.health}) print(f狗狗的品种是{self.strain}) pass ​ class Penguin: def __init__(self, name, love, health, sex): self.name name self.love love self.health health self.sex sex ​ def print_info(self): print(f企鹅的名字是的{self.name}) print(f企鹅的亲密值是的{self.love}) print(f企鹅的健康值是的{self.health}) print(f企鹅的性别是的{self.sex}) ​4.使用继承优化宠物系统 ​ 继承的核心思想子类与父类是is-a的关系 即子类是父类 (属于描述 也属于约束) 表示子类必须属于父类描述的这一大范围 才可以使用继承 ​ ​ 使用继承优化宠物系统 宠物类 将各个重复类中 重复的 共同的信息 编写到父类中、 子类 书写各个子类独有的信息 ​ 狗狗类 属性名字 亲密值 健康值 品种 方法介绍狗狗信息 企鹅类 属性名字 亲密值 健康值 性别 方法介绍企鹅信息 ​ ​ 创建子类对象 并不会创建父类对象(注意) ​ ​ class Pet: def __int__(self, name, love, health): self.name name # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 self.love love # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 self.health health # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 ​ def print_info(self): print(f宠物的名字是{self.name}) print(f宠物的亲密值是{self.love}) print(f宠物的健康值是{self.health}) pass ​ class Dog(Pet): def __init__(self,strain,name,love,health): super().__int__(name,love,health) self.strain strain pass ​ class Penguin(Pet): def __init__(self, sex , name, love, health): self.sex sex super().__int__(name,love,health) # Java 中的写法 super(name,health,love) pass ​ d1 Dog(金毛, 大黄 , 100 , 100) d1.print_info() ​ print(---------------------------------------------------------) ​ ​ p1 Penguin(雌性 , 大白 , 100 , 100) p1.print_info()4.1 什么是继承继承让一个类子类 / 派生类去获取另一个类父类 / 基类的属性和方法实现代码复用不用重复写相同代码。父类被继承的类 子类继承别人的类语法class 父类名: # 父类代码 ​ class 子类名(父类名): # 子类代码5. 方法重写如果子类的方法名和父类一样子类优先执行自己的方法覆盖父类。class Animal: def eat(self): print(动物吃东西) ​ class Dog(Animal): # 重写父类eat def eat(self): print(狗狗吃骨头) ​ dog Dog() dog.eat() # 输出狗狗吃骨头 之前通过子类调用父类中的 print_info()方法 只能打印所有宠物共有的三个信息 所以我们可以在子类中再编写新的方法 打印独有的信息 并且将父类中的打印方法 复用 实现组合的效果 ​ 现在我们在子类中编写了新的方法 实现了组合效果 但是每个子类都有一个不同的名字 这样随着后续宠物类的增多 将会导致程序结构混乱 我们应该使用一个统一的名字 不管任何宠物打印信息 都使用一个 程序结构更加统一 方便调用 ​ ​ class Pet: def __init__(self, name, love, health): self.name name # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 self.love love # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 self.health health # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 ​ def print_info(self): print(f宠物的名字是{self.name}) print(f宠物的亲密值是{self.love}) print(f宠物的健康值是{self.health}) pass ​ class Dog(Pet): def __init__(self,strain,name,love,health): super().__init__(name,love,health) self.strain strain ​ def print_dog(self): super().print_info() print(f狗狗的品种是{self.strain}) pass ​ class Penguin(Pet): def __init__(self, sex , name, love, health): self.sex sex super().__init__(name,love,health) # Java 中的写法 super(name,health,love) ​ def print_penguin(self): print(f企鹅的性别是{self.sex}) super().print_info() pass ​ d1 Dog(金毛, 大黄 , 100 , 100) d1.print_dog() d1.print_info() ​ print(---------------------------------------------------------) ​ ​ p1 Penguin(雌性 , 大白 , 100 , 100) p1.print_penguin() 方法重写 子类的方法声明与父类一致 Method Override 子类方法覆盖父类方法 ​ ​ 单继承下的MRO机制 调用某个方法 先从本类(子类)中查找 找到则直接调用 找不到则去直接父类中查找 后续重复这个操作 直到找到为止 ​ ​ class Pet: def __init__(self, name, love, health): self.name name # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 self.love love # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 self.health health # 这里的self 指向某个具体的子类对象 当前使用的哪个子类对象 就指向谁 ​ def print_info(self): print(f宠物的名字是{self.name}) print(f宠物的亲密值是{self.love}) print(f宠物的健康值是{self.health}) pass ​ class Dog(Pet): def __init__(self,strain,name,love,health): super().__init__(name,love,health) self.strain strain ​ def print_info(self): super().print_info() print(f狗狗的品种是{self.strain}) pass ​ class Penguin(Pet): def __init__(self, sex , name, love, health): self.sex sex super().__init__(name,love,health) # Java 中的写法 super(name,health,love) ​ def print_info(self): print(f企鹅的性别是{self.sex}) super().print_info() ​ ​ pass ​ d1 Dog(金毛, 大黄 , 100 , 100) d1.print_info() ​ print(---------------------------------------------------------) ​ p1 Penguin(雌性 , 大白 , 100 , 100) p1.print_info()6. 单继承下的MRO(Method Resolution Order)机制Method Resolution Order : 方法查找顺序单继承下的MRO,一层一层往上找​ ​ class A: # def test(self): # print(A 类中的test函数) ​ # def __str__(self): # return A 类中重写的__str__()函数 pass ​ class B(A): # def test(self): # print(B 类中的test函数) ​ # def __str__(self): # return B 类中重写的__str__()函数 pass ​ class C(B): # def test(self): # print(C 类中的test函数) ​ # def __str__(self): # return C 类中重写的__str__()函数 pass ​ c1 C() print(C.__mro__) # (class __main__.C, class __main__.B, class __main__.A, class object) # c1.test() print(c1.__str__())7.多继承下的MRO机制多继承一个子类继承多个父类多继承下的MROPython 会从左往右找再往上找到就停止⚠️ 开发中尽量少用复杂多继承容易出现代码混乱。 Python是支持多继承的 一个类直接继承多个父类 Java是单根继承 多个类之间使用逗号分割即可 在多继承场景下 方法的MRO机制 如果存在多个并列的父类 那么方法的查找顺序 则从左到右 找到则直接调用 否则继续向上查找 ​ 分析object类存在的意义 面向对象 也可以理解为 所有类对象都面向object 属于此类的子类对象 所有的类默认继承此类 此类表示对象 所以在此类中规定了任何一个对象 应该具备的行为 比如 __del__ __new__ __init__ 等等 ​ ​ class Person: def __str__(self): return Person类中的__str__()函数 pass ​ class YellowPerson(Person): def __str__(self): return YellowPerson类中的__str__()函数 pass ​ class Chinese(Person): def __str__(self): return Chinese类中的__str__()函数 pass ​ class Student(YellowPerson,Chinese): def __str__(self): return Student类中的__str__()函数 pass ​ s1 Student() print(Student.__mro__) print(s1)8.super () 调用父类方法重写之后如果还想保留父类原来的逻辑用super()class Animal: def eat(self): print(动物吃东西) ​ class Dog(Animal): def eat(self): super().eat() # 调用父类的eat方法 print(狗狗吃骨头) ​ dog Dog() dog.eat() #输出 #动物吃东西 #狗狗吃骨头super () 最常用于__init__构造函数重点继承时构造方法__init__⚠️ 如果子类自己写了__init__不会自动调用父类的init必须手动用 super 调用。class Animal: def __init__(self, name): self.name name ​ class Dog(Animal): def __init__(self, name, age): # 调用父类构造把name传给父类 super().__init__(name) self.age age ​ dog Dog(旺财, 3) print(dog.name) print(dog.age)9.issubclass () 判断继承关系print(issubclass(Dog, Animal)) #True Dog是Animal子类10.多态10.1 概念多态同一个接口方法名传入不同的对象执行不一样的代码。 前提条件Python 实现多态一般要满足要有继承关系子类重写父类的方法Python 是鸭子类型就算没有继承也能实现多态# 父类 class Animal: def speak(self): pass ​ # 子类1 class Dog(Animal): def speak(self): print(汪汪汪) ​ # 子类2 class Cat(Animal): def speak(self): print(喵喵喵) ​ # 定义一个统一的函数接收动物对象 def make_sound(animal): animal.speak() # 同一个方法名speak ​ # 传入不同对象产生不同效果 dog Dog() cat Cat() ​ make_sound(dog) make_sound(cat)输出汪汪汪 喵喵喵make_sound函数根本不用关心你是 Dog 还是 Cat只要对象有speak()方法就行。这就是多态。10.2多态的好处1.代码灵活易扩展以后新增动物不用改make_sound函数代码class Duck(Animal): def speak(self): print(嘎嘎嘎) ​ duck Duck() make_sound(duck)直接新增子类原有函数完全不用修改 →开闭原则对扩展开放对修改关闭降低耦合调用方和具体的类解绑10.3 Python 鸭子类型Python 特色多态不需要继承“鸭子测试”看起来像鸭子走路像鸭子叫起来像鸭子那它就是鸭子。 Python 不强制要求继承同一个父类只要对象拥有同名方法就可以实现多态。class Dog: def speak(self): print(汪汪汪) class Cat: def speak(self): print(喵喵喵) class Person: def speak(self): print(你好呀) def make_sound(animal): animal.speak() make_sound(Dog()) make_sound(Cat()) make_sound(Person())三个类没有任何继承关系但是都有speak()就可以传入同一个函数。Java/C 必须继承父类才能做多态Python 不需要这就是鸭子类型。10.4 抽象父类规范子类必须重写方法有时候你希望子类必须重写父类的 speak 方法不然报错。 这时就要用到abc模块创建抽象基类。from abc import ABC, abstractmethod class Animal(ABC): # 抽象方法没有实现强制子类必须重写 abstractmethod def speak(self): pass class Dog(Animal): def speak(self): print(汪汪汪) # 如果子类没有重写speak实例化的时候就报错 # class Cat(Animal): # pass # cat Cat() # TypeError dog Dog() dog.speak()抽象类不能直接创建对象Animal()会报错。abstractmethod表示抽象方法 即没有方法体的方法抽象类作用制定一套标准、接口约束子类必须实现某些方法让多态更规范。11 多态案例from abc import ABC, abstractmethod # 支付抽象父类 class Pay(ABC): abstractmethod def pay_money(self,money): pass # 微信支付 class WeChatPay(Pay): def pay_money(self, money): print(f微信支付{money}元) # 支付宝支付 class AliPay(Pay): def pay_money(self, money): print(f支付宝支付{money}元) # 统一收银台函数多态入口 def checkout(pay_obj, money): pay_obj.pay_money(money) checkout(WeChatPay(), 100) checkout(AliPay(), 200)后面新增银联支付只需要新建一个子类不用修改checkout函数。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

沈阳手机网站从零搭建避坑指南:搞懂域名服务器与SEO核心逻辑 2026/9/27 6:26:15

沈阳手机网站从零搭建避坑指南:搞懂域名服务器与SEO核心逻辑

沈阳手机网站从零搭建避坑指南:搞懂域名服务器与SEO核心逻辑 域名解析报错 502?服务器配置一塌糊涂?别慌,这是很多沈阳本地企业做手机网站时最常遇到的“拦路虎”。很多老板觉得买个域名、租台服务器就能开工,结果上线后发现手机打开慢如蜗牛,百…

阅读更多 →
CODESYS安装配置全攻略:从下载到PLC连接避坑指南 2026/9/27 6:26:15

CODESYS安装配置全攻略:从下载到PLC连接避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
手机能当工业相机用吗?揭秘机器视觉的硬件本质差异 2026/9/27 6:26:15

手机能当工业相机用吗?揭秘机器视觉的硬件本质差异

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
搞定网站域名所有权证明,顺带讲透性能优化避坑指南 2026/9/27 6:26:02

搞定网站域名所有权证明,顺带讲透性能优化避坑指南

搞定网站域名所有权证明,顺带讲透性能优化避坑指南 备案流程一头雾水?别慌,很多站长卡在“网站域名所有权证明”这一步,明明域名就在手里,系统却提示“无法验证归属”,气得想摔键盘。这时候,如果你只顾着盯着报错信息死磕,容易陷入死胡同。其实,搞定…

阅读更多 →
ip域名找网站一文搞懂:避坑指南与真实报价拆解 2026/9/27 6:25:50

ip域名找网站一文搞懂:避坑指南与真实报价拆解

ip域名找网站一文搞懂:避坑指南与真实报价拆解 备案流程一头雾水?很多老板拿到IP地址或域名后,卡在“怎么把网站搞起来”这一步。其实,ip域名找网站这件事,核心不是找谁,而是搞清楚你手里有什么、缺什么,以及钱该花在哪。今天这篇内容,不整虚的…

阅读更多 →
分支嵌套结构示例 2026/9/27 6:25:43

分支嵌套结构示例

分支嵌套结构示例if 条件1:条件1成立时要做的事情if 条件A:条件A成立时要做的事情else:条件A不成立时要做的事情 else:条件1不成立时要做的事情if 条件B:条件B成立时要做的事情elif 条件C:条件C成立时要做事情else:上述条件(BC)均不成立时要做…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉