10天玩转Python第7天:python 面向对象 全面详解与代码示例

news2024/9/23 5:15:11

今日内容

  • 封装(定义类的过程)

    • 案例(存放家具)
  • 继承

  • 多态

  • 封装的补充

    • 私有和公有权限
    • 属性的分类(实例属性, 类属性)
    • 方法的分类(实例方法, 类方法, 静态方法)

封装案例

 

 
# 定义家具类
class HouseItem:
    """家具类"""
    def __init__(self, name, area):
        """添加属性的方法"""
        self.name = name
        self.area = area
    def __str__(self):
        return f'家具名字{self.name}, 占地面积 {self.area} 平米'
class House:
    """房子类"""
    def __init__(self, name, area):
        self.name = name  # 户型
        self.total_area = area  # 总面积
        self.free_area = area   # 剩余面积
        self.item_list = []     # 家具名称列表
    def __str__(self):
        return f"户型: {self.name}, 总面积:{self.total_area}平米, 剩余面积: {self.free_area} 平米, " \
               f"家具名称列表: {self.item_list}"
    def add_item(self, item):  # item  表示的家具的对象
        # 判断房子的剩余面积(self.free_area)和家具的占地面积(item.area)之间的关系
        # self 表示的 房子对象, 缺少一个家具对象使用传参解决
        if self.free_area > item.area:
            # 添加家具, ---> 向列表中添加数据
            self.item_list.append(item.name)
            # 修改剩余面积
            self.free_area -= item.area
            print(f'{item.name} 添加成功')
        else:
            print('剩余面积不足, 换个大房子吧')
# 创建家具对象
bed = HouseItem('席梦思', 4)
chest = HouseItem('衣柜', 2)
table = HouseItem('餐桌', 1.5)
print(bed)
print(chest)
print(table)
# 创建房子对象
house = House('三室一厅', 150)
print(house)
# 添加 床
house.add_item(bed)
print(house)

案例 2

 

 
需求: 某 Web 项目登录页面包含: 用户名, 密码, 验证码, 登录按钮 和登录的方法
书写代码实现以上功能, 登录方法中使用 print 输出即可
类名: LoginPage
属性: 用户名(username), 密码(password), 验证码(code), 登录按钮(button)
方法: 登录(login)   __init__
 

 
class LoginPage:
    def __init__(self, username, password, code):
        self.username = username
        self.password = password
        self.code = code
        self.btn = '登录'
    def login(self):
        print(f'1. 输入用户名 {self.username}')
        print(f'2. 输入密码 {self.password}')
        print(f'3. 输入验证码 {self.code}')
        print(f"4. 点击按钮 {self.btn}")
login = LoginPage('admin', '123456', '8888')
login.login()

私有和公有

 

 
1. 在 Python 中定义的方法和属性, 可以添加访问控制权限(即在什么地方可以使用这个属性和方法)
2. 访问控制权限分为两种, 公有权限, 私有权限
3. 公有权限
    > 直接书写的方法和属性, 都是公有的
    > 公有的方法和属性, 可以在任意地方访问和使用
4. 私有权限
    > 在类内部, 属性名或者方法名 前边加上两个 下划线 , 这个属性或者方法 就变为 私有的 
    > 私有的方法和属性, 只能在当前类的内部使用
5. 什么时候定义私有
    > 1. 某个属性或者方法,不想在类外部被访问和使用, 就将其定义为私有即可
    > 2. 测试中,一般不怎么使用, 直接公有即可
    > 3. 开发中,会根据需求文档, 确定什么作为私有
6. 如果想要在类外部操作私有属性, 方法是, 在类内部定义公有的方法, 我们通过这个公有方法去操作
# 补充:
# 对象.__dict__   魔法属性, 可以将对象具有的属性组成字典返回
  • 案例

     

     
    定义一个 Person 类, 属性 name, age(私有)
  • 代码

     

     
    class Person:
        def __init__(self, name, age):
            self.name = name   # 姓名
            # 私有的本质, 是 Python 解释器执行代码,发现属性名或者方法名前有两个_, 会将这个名字重命名
            # 会在这个名字的前边加上 _类名前缀,即 self.__age ===> self._Person__age
            self.__age = age  # 年龄, 将其定义为私有属性, 属性名前加上两个 _
        def __str__(self):  # 在类内部可以访问私有属性的
            return f'名字: {self.name}, 年龄: {self.__age}'
    xm = Person('小明', 18)
    print(xm)
    # 在类外部直接访问 age 属性
    # print(xm.__age)  # 会报错, 在类外部不能直接使用私有属性
    # 直接修改 age 属性
    xm.__age = 20  # 这个不是修改私有属性, 是添加了一个公有的属性 __age
    print(xm)  # 名字: 小明, 年龄: 18
    print(xm._Person__age)  # 能用但是不要用  18
    xm._Person__age = 19
    print(xm)  # 名字: 小明, 年龄: 19

继承

 

 
1. 继承描述的是类与类之间的关系
2. 继承的好处: 减少代码的冗余(相同的代码不需要多次重复书写), 可以直接使用

语法

 

 
# class A(object):
class A: # 没有写父类,但也有父类, object, object 类是 Python 中最顶级(原始)的类
    pass
class  B(A):  # 类 B, 继承类 A
    pass 
 

 
术语:
1. A 类, 称为是 父类(基类)
2. B 类, 称为是 子类(派生类) 
单继承: 一个类只继承一个父类,称为单继承
继承之后的特点:
    > 子类(B)继承父类(A)之后, 子类的对象可以直接使用父类中定义的公有属性和方法
  • 案例

     

     
    1. 定义一个 动物类, 吃 
    2. 定义一个 狗类, 继承动物类, 吃, 叫
    3. 定义一个 哮天犬类, 继承 狗类 
  • 代码

     

     
    # 1. 定义一个 动物类, 吃
    class Animal:
        def eat(self):
            print('要吃东西')
    # 2. 定义一个 狗类, 继承动物类, 吃, 叫
    class Dog(Animal):
        def bark(self):
            print('汪汪汪叫....')
    # 3. 定义一个 哮天犬类, 继承 狗类
    class XTQ(Dog):
        pass
    # 创建 动物类的对象
    # ani = Animal()
    # ani.eat()
    # 创建狗类对象
    # dog = Dog()
    # dog.eat()  # 调用父类中的方法
    # dog.bark()   # 调用自己类中方法
    # 创建哮天犬类对象
    xtq = XTQ()
    xtq.bark()  # 调用 父类 Dog 类的方法
    xtq.eat()   # 可以调用 父类的父类中的方法
  • 结论

     

     
    python 中 对象.方法() 调用方法
    1. 现在自己的类中的去找有没有这个方法 如果有,直接调用
    2. 如果没有去父类中 查找, 如果有,直接调用
    3. 如果没有, 去父类的父类中查找, 如果有直接调用
    4 ...
    5. 如果 object 类中有,直接调用, 如果没有,代码报错

重写

 

 
重写: 在子类中定义了和父类中名字相同的方法, 就是重写
重写的原因: 父类中的方法,不能满足子类对象的需求,所以重写
重写之后的特点: 调用子类字节的方法, 不再调用父类中的方法
重写的方式: 
    >1. 覆盖(父类中功能完全抛弃,不要,重写书写)
    >2. 扩展(父类中功能还调用,只是添加一些新的功能) (使用较多)
覆盖
 

 
1. 直接在子类中 定义和父类中名字相同的方法
2. 直接在方法中书写新的代码
 

 
class Dog:
    def bark(self):
        print('汪汪汪叫.....')
class XTQ(Dog):
    # XTQ 类bark 方法不再是汪汪汪叫, 改为 嗷嗷嗷叫
    def bark(self):
        print('嗷嗷嗷叫...')
xtq = XTQ()
xtq.bark()
扩展父类中的功能
 

 
1. 直接在子类中 定义和父类中名字相同的方法
2. 在合适的地方调用 父类中方法  super().方法()
3. 书写添加的新功能
 

 
class Dog:
    def bark(self):
        print('汪汪汪叫.....')
        print('汪汪汪叫.....')
class XTQ(Dog):
    # XTQ 类bark 方法不再是汪汪汪叫, 改为
    # 1. 先 嗷嗷嗷叫(新功能) 2, 汪汪汪叫(父类中功能)  3. 嗷嗷嗷叫 (新功能)
    def bark(self):
        print('嗷嗷嗷叫...')
        # 调用父类中的代码
        super().bark()  # print() 如果父类中代码有多行呢?
        print('嗷嗷嗷叫...')
xtq = XTQ()
xtq.bark()

多态[了解]

 

 
1. 是一种写代码,调用的一种技巧
2. 同一个方法, 传入不同的对象, 执行得到不同的结果, 这种现象称为是多态
3. 多态 可以 增加代码的灵活度
--------
哪个对象调用方法, 就去自己的类中去查找这个方法, 找不到去父类中找

属性和方法

 

 
Python 中一切皆对象. 
即 使用 class 定义的类 也是一个对象

对象的划分

实例对象(实例)
 

 
1. 通过 类名() 创建的对象, 我们称为实例对象,简称实例
2. 创建对象的过程称为是类的实例化
3. 我们平时所说的对象就是指 实例对象(实例)
4. 每个实例对象, 都有自己的内存空间, 在自己的内存空间中保存自己的属性(实例属性)
类对象(类)
 

 
1. 类对象 就是 类, 或者可以认为是 类名
2. 类对象是 Python 解释器在执行代码的过程中 创建的
3. 类对象的作用: ① 使用类对象创建实例 类名(),  ② 类对象 也有自己的内存空间, 可以保存一些属性值信息 (类属性)
4. 在一个代码中, 一个类 只有一份内存空间

属性的划分

实例属性
  • 概念: 是实例对象 具有的属性

  • 定义和使用

     

     
    在 init 方法中, 使用 self.属性名 = 属性值 定义
    在方法中是 使用 self.属性名 来获取(调用)
  • 内存

     

     
    实例属性,在每个实例中 都存在一份
  • 使用时机

     

     
    1. 基本上 99% 都是实例属性,即通过 self 去定义
    2. 找多个对象,来判断这个值是不是都是一样的, 如果都是一样的, 同时变化,则一般定义为 类属性, 否则定义为 实例属性

类属性
  • 概念: 是 类对象 具有的属性

  • 定义和使用

     

     
    在类内部,方法外部,直接定义的变量 ,就是类属性
    使用:  类对象.属性名 = 属性值  or  类名.属性名 = 属性值 
    类对象.属性名  or  类名.属性名
  • 内存

     

     
    只有 类对象 中存在一份

方法的划分

 

 
方法, 使用 def 关键字定义在类中的函数就是方法
实例方法(最常用)
  • 定义

     

     
    # 在类中直接定义的方法 就是 实例方法
    class Demo:
        def func(self):   # 参数一般写作 self,表示的是实例对象
            pass
  • 定义时机(什么时候用)

     

     
    如果在方法中需要使用实例属性(即需要使用 self), 则这个方法必须定义为 实例方法 
  • 调用

     

     
    对象.方法名()   # 不需要给 self 传参
类方法(会用)
  • 定义

     

     
    # 在方法名字的上方书写 @classmethod 装饰器(使用 @classmethod 装饰的方法)
    class Demo:
        @classmethod
        def func(cls):  # 参数一般写作 cls, 表示的是类对象(即类名) class
            pass 
  • 定义时机(什么时候用)

     

     
    1. 前提, 方法中不需要使用 实例属性(即 self)
    2. 用到了类属性, 可以将这个方法定义为类方法,(也可以定义为实例方法)
  • 调用

     

     
    # 1. 通过类对象调用
    类名.方法名()  # 也不需要给 cls 传参, python 解释器自动传递
    # 2. 通过实例对象调用
    实例.方法名()  # 也不需要给 cls 传参, python 解释器自动传递
静态方法(基本不用)
  • 定义

     

     
    # 在方法名字的上方书写 @staticmethod 装饰器(使用 @staticmethod 装饰的方法)
    class Demo:
        @staticmethod
        def func():   # 一般没有参数
            pass 
  • 定义时机(什么时候用)

     

     
    1. 前提, 方法中不需要使用 实例属性(即 self)
    2. 也不使用 类属性, 可以将这个方法定义为 静态方法
  • 调用

     

     
    # 1. 通过类对象调用
    类名.方法名() 
    # 2. 通过实例对象调用
    实例.方法名()  

练习

练习 1
 

 
定义一个 Dog 类, 定义一个类属性 count,用来记录创建该类对象的个数. (即每创建一个对象,count 的值就要加1)实例属性 name
 

 
class Dog:
    # 定义类属性
    count = 0
    # 定义实例属性, init 方法中
    def __init__(self, name):
        self.name = name   # 实例属性
        # 因为每创建一个对象,就会调用 init 方法, 就将个数加 1 的操作,写在 init 方法中
        Dog.count += 1
# 在类外部
# 打印输出目前创建几个对象
print(Dog.count)  # 0
# 创建一个对象
dog1 = Dog('小花')
# 打印输出目前创建几个对象
print(Dog.count)  # 1
dog2 = Dog   # 不是创建对象, 个数不变的
dog3 = dog1  # 不是创建对象, 个数不变的
print(Dog.count)  # 1
dog4 = Dog('大黄')  # 创建一个对象 , 个数 + 1
print(Dog.count)  # 2
dog5 = Dog('小白')
print(Dog.count)  # 3
# 补充, 可以使用 实例对象.类属性名 来获取类属性的值  (原因, 实例对象属性的查找顺序, 先在实例属性中找,找到直接使用
# 没有找到会去类属性中 找, 找到了可以使用, 没有找到 报错)
print(dog1.count)  # 3
print(dog4.count)  # 3
print(dog5.count)  # 3

题目 2

定义一个游戏类 Game , 包含实例属性 玩家名字(name)

  1. 要求记录游戏的最高分(top_score 类属性),

  2. 定义方法: show_help 显示游戏的帮助信息 输出这是游戏的帮助信息

  3. 定义方法: show_top_score, 打印输出游戏的最高分

  4. 定义方法: start_game, 开始游戏, 规则如下

    1. 使用随机数获取本次游戏得分 范围 (10 - 100 )之间

    2. 判断本次得分和最高分之间的关系

      • 如果本次得分比最高分高,

        • 修改最高分
      • 如果分数小于等于最高分,则不操作

    3. 输出本次游戏得分

  1. 主程序步骤

     

     
    # 1) 创建一个 Game 对象  小王
    # 2) 小王玩一次游戏,
    # 3) 查看历史最高分
    # 4) 小王再玩一次游戏
    # 5) 查看历史最高分
    # 6) 查看游戏的帮助信息

  • 基本版本

     

     
    import random
    class Game:
        # 类属性, 游戏的最高分
        top_score = 0
        def __init__(self, name):
            # 定义实例属性 name
            self.name = name
        def show_help(self):
            print('这是游戏的帮助信息')
        def show_top_score(self):
            print(f'游戏的最高分为 {Game.top_score}')
        def start_game(self):
            print(f'{self.name} 开始一局游戏, 游戏中 ...,', end='')
            score = random.randint(10, 100)  # 本次游戏的得分
            print(f'本次游戏得分为 {score}')
            if score > Game.top_score:
                # 修改最高分
                Game.top_score = score
    xw = Game('小王')
    xw.start_game()
    xw.show_top_score()
    xw.start_game()
    xw.show_top_score()
    xw.show_help()
  • 优化 (使用 类方法和静态方法)

     

     
        @staticmethod
        def show_help():
            print('这是游戏的帮助信息')
        @classmethod
        def show_top_score(cls):
            print(f'游戏的最高分为 {cls.top_score}')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1315974.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LT7911D是TYPE-C/DP或者EDP转2 PORT MIPI和LVDS加音频

1.概述: T7911D是一款高性能TYPE-C/DP/EDP转2 PORT MIPI或者LVDS的芯片,目前主要在AR/VR或者显示器上应用的很多,对于DP1.2输入,LT7911D可配置为1/2/4车道。自适应均衡化使其适用于长电缆应用,最大带宽可达21.6Gbps。…

Vue3报错: ‘defineProps‘ is not defined,解决方法

问题出现: 今天在使用 <script setup>组合式 API 的语法糖的时候&#xff0c;定义defineProps时候报错&#xff1a; ‘defineProps’ is not defined 查了一下资料&#xff0c;这是因为eslint的语法校验导致的问题。 解决方法1&#xff1a; 在项目根目录的文件.eslin…

时序预测 | Python实现XGBoost电力需求预测

时序预测 | Python实现XGBoost电力需求预测 目录 时序预测 | Python实现XGBoost电力需求预测预测效果基本描述程序设计参考资料预测效果 基本描述 该数据集因其每小时的用电量数据以及 TSO 对消耗和定价的相应预测而值得注意,从而可以将预期预测与当前最先进的行业预测进行比较…

JS中的String常用的实例方法

splice():分隔符 把字符串以分隔符的形式拆分为数组 const str pink,red;const arr str.split(,);console.log(arr);//Array[0,"pink";1:"red"]const str1 2022-4-8;const arr1 str1.split(-);console.log(arr1);//Array[0,"2022";1:"…

深入理解网络 I/O:单 Group 混杂模式|多 Group 主从模式

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

DS考研真题总结——客观题(1)

开始整理真题中的客观小题&#xff0c;至于和算法有关的大题统一最后整理~ 定义背诵&#xff1a;数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效…

现代雷达车载应用——第2章 汽车雷达系统原理 2.2节 汽车雷达架构

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 2.2 汽车雷达架构 从顶层来看&#xff0c;基本的汽车雷达由发射器&#xff0c;接收器和天线组成。图2.2给出了一种简化的单通道连续波雷达结构[2]。这…

javaEE -17(13000字 CSS3 入门级教程)

一&#xff1a;CSS3 简介 CSS3 是 CSS2 的升级版本&#xff0c;它在 CSS2 的基础上&#xff0c;新增了很多强大的新功能&#xff0c;从而解决一些实际面临的问题&#xff0c;CSS3 在未来会按照模块化的方式去发展&#xff1a;https://www.w3.org/Style/CSS/current-work.html …

Python基础01-环境搭建与输入输出

零、文章目录 Python基础01-环境搭建与输入输出 1、Python概述 &#xff08;1&#xff09;为什么要学习Python 技术趋势&#xff1a;Python自带明星属性&#xff0c;热度稳居编程语言界前三 简单易学&#xff1a;开发代码少&#xff0c;精确表达需求逻辑&#xff1b;33个关…

linux记录

一、修改eth0网口静态IP 1、sudo vim /etc/network/interfaces 2、按E进入编辑模式&#xff0c;按i进入编辑输入&#xff1a; auto eth0 iface eth0 inet static address 192.168.3.223 netmask 255.255.255.0 gateway 192.168.3.13、按Esc退出编辑&#xff1b;:wq保存文件并…

移植LVGL到像素屏,从此玩转像素屏0门槛

硬件方面 先上渲染图 实物图 配置 主控&#xff1a;esp32 micro32 plus主频&#xff1a;240MhzFlash&#xff1a;8MPSRAM&#xff1a;2M 软件方面 众所周知&#xff0c;LVGL是一个十分优秀的图形框架&#xff0c;小到几百kb的单片机&#xff0c;大到Linux都可以运行。既然它…

【Qt QML 入门】TextEdit

TextEdit可以显示多行可编辑的格式化文。默认是无边框的&#xff0c;可以和父控件完美融合。 import QtQuick import QtQuick.Window import QtQuick.ControlsWindow {id: winwidth: 800height: 600visible: trueTextEdit {id: textEditanchors.centerIn: parenttext: "He…

【ArkTS】生命周期

页面生命周期 通常Entry修饰的组件称为页面&#xff0c;其拥有页面生命周期 onPageShow&#xff1a;页面每次显示时触发。onPageHide&#xff1a;页面每次隐藏时触发&#xff08;通常是路由跳转到其他页面了&#xff09;。onBackPress&#xff1a;当用户点击返回按钮时时触发…

谷歌的开源供应链安全

本内容是对Go项目负责人Russ Cox 在 ACM SCORED 活动上演讲内容[1]的摘录与整理。 SCORED 是Software Supply Chain Offensive Research and Ecosystem Defenses的简称, SCORED 23[2]于2023年11月30日在丹麦哥本哈根及远程参会形式举行。 摘要 &#x1f4a1; 谷歌在开源软件供应…

​SQL (关系型) 数据库-fastapi集成

SQL (关系型) 数据库 - FastAPI FastAPI不需要你使用SQL(关系型)数据库。 但是您可以使用任何您想要的关系型数据库。 在这里&#xff0c;让我们看一个使用着SQLAlchemy的示例。 您可以很容易地将SQLAlchemy支持任何数据库&#xff0c;像&#xff1a; PostgreSQLMySQLSQLi…

Visual Studio 2022封装C代码为x64和x86平台动态库

1.引言 本文介绍如何使用Visual Studio 2022将C语言函数封装成x64和x86平台上使用的动态链接库(dll文件)并生成对应的静态链接库(lib文件)&#xff0c;以及如何在C程序中调用生成的dll。 程序下载&#xff1a; 2.示例C语言程序 假设需要开发一个动态链接库&#xff0c;实现复…

Linux(操作系统)面经——part 1(持续更新中......)

1、说一说常用的 Linux 命令 mkdir创建文件夹&#xff0c;touch创建文件&#xff0c;mv移动文件内容或改名 rm-r 文件名&#xff1a;删除文件 cp拷贝&#xff1a;cp 文件1 文件2&#xff0c;cp-r跨目录拷贝 cp-r 路径1 路径2 vi 插入 &#xff1a;wqb保存退出 :q!强制退出…

W25N01GV 芯片应用

项目中处于成本考虑&#xff0c;要把Nor Flash换成低成本的Nand Flash。 这里总结下芯片应用。 总体概述&#xff1a; 1&#xff09;W25N01&#xff08;NandFlash&#xff09;和W25Q&#xff08;Nor Flash&#xff09;的操作大不一样。 NandFlash擦除以块&#xff08;128KB&…

计算BMI指数-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第19讲。 计算BMI指数&…

【TB作品】基于单片机的机械通风控制系统,实时温度和二氧化碳浓度

硬件&#xff1a; &#xff08;1&#xff09;51系列单片机&#xff0c;拟采用STC89C52RC&#xff1b; &#xff08;2&#xff09;DS18B20温度传感器&#xff1b; &#xff08;3&#xff09;二氧化碳浓度传感器&#xff1a;https://item.taobao.com/item.htm?spma21n57.1.0.0.1…