• 嵌入式Python高级


    嵌入式Python高级 str字符串 set集合 dict字典 slice切片 推导式 高级变量公共语法 内置函数 面向对象  __int__  __str___  私有化  属性私有化  方法私有化  面向对象三大特征 封装 继承 多态

    一、str字符串

    字符串就是一串字符,是编程语言中表示文本的数据类型

    1. 字符串定义

    Python中可以使用一对双引号或者一对单引号定义字符串

    1. str1 = 'hello'
    2. str2 = "hello"

    2. 获取字符串中元素

    和列表一样,字符串也是通过索引获取元素

    1. str = "hello"
    2. # 获取第三个元素
    3. ele = str[2] # l

    3. 遍历字符串

    可以通过for循环遍历字符串

    1. str = 'hello'
    2. for ele in str:
    3. print(ele)

    4. 字符串的常见操作

    4.1. 判断

    4.2. 查找替换
     4.3. 切割

    4.4. 去空白
     

    5. 练习-用户名和密码校验

    需求

    • 用户名和密码格式校验程序
    • 要求从键盘输入用户名和密码,分别校验格式是否符合规则
      • 如果符合,打印用户名合法密码合法
      • 如果不符合,打印出不符合的原因,并提示重新输入
    • 用户名长度6-20,用户名必须以字母开头
    • 密码长度至少6位,不能为纯数字,不能有空格

    分析

    1.从键盘输入用户名(需要while循环)
    2.长度6-20
    3.必须字母开头

    4.输入密码(while循环)
    5.密码长度至少6位
    6.不能为纯数字
    7.不能有空格

    实现

    1. while True:
    2. # 1.从键盘输入用户名(需要while循环)
    3. name = input('请输入用户名:')
    4. # 2.长度6-20
    5. if not (len(name) >= 6 and len(name) <= 20):
    6. print('用户名必须6到20位')
    7. continue
    8. # 3.必须字母开头 ab A-Z
    9. # 获取第一个字母 是否是a-z A-Z a
    10. ele = name[0]
    11. if not ele.isalpha():
    12. print('用户名第一个必须为字母')
    13. continue
    14. # 用户名满足
    15. print('用户名合法')
    16. break
    17. # 4.输入密码(while循环)
    18. while True:
    19. pwd = input('请输入密码')
    20. # 5.密码长度至少6位
    21. if len(pwd) < 6:
    22. print('密码长度至少为6位')
    23. continue
    24. # 6.不能为纯数字
    25. if pwd.isdecimal():
    26. print('密码不能为纯数字')
    27. continue
    28. # 7.不能有空格
    29. # ' 张 三 '
    30. if ' ' in pwd:
    31. print('密码不能有空格')
    32. continue
    33. print('密码合法')
    34. break

     扩展

    • isalpha()字符串中所有元素都是字母,则返回True
    • isdecimal()字符串中都是数字,则返回True

    二、set集合

    set被称为集合,是无序的,并且集合中的元素是唯一的 

     1. 集合的创建

    s = {'张三','李四','王五'}

     集合是无序的

    1. s = {'张三','李四','王五'}
    2. print(s)

    结果: 

    {'王五', '张三', '李四'}

    集合元素唯一

    1. s = {'张三','李四','王五','张三'}
    2. print(s)

    结果:

    {'李四', '张三', '王五'}

    2. 遍历集合中元素 

    通过for循环遍历集合中的元素

    1. s = {'张三','李四','王五'}
    2. # 遍历集合
    3. for ele in s:
    4. print(ele)

    3. 集合中添加元素 

    集合可以通过add方法添加元素

    1. s = {'张三','李四','王五'}
    2. # # 添加赵六 add
    3. s.add('赵六')

    4. 集合删除元素 

    remove删除,如果有 直接删除,如果没有 程序报错

    1. s = {'张三','李四','王五'}
    2. # 删除张三
    3. s.remove('张三')

    pop删除,随机删除集合中的元素并返回,如果集合中没有元素,则程序报错 

    1. s = {'张三','李四','王五'}
    2. # pop 随机删除
    3. print(s.pop())

    discard删除,元素存在则直接删除,如果元素不存在,则不做任何操作 

    1. s = {'张三','李四','王五'}
    2. # discard 删除元素 如果元素不存在,不做任何处理
    3. s.discard('林青霞')

    三、dict字典

    1. 字典简介

    dictionary(字典) 是 除列表以外 Python 之中 最灵活 的数据类型,类型为dict

    • 字典同样可以用来存储多个数据
    • 字典使用键值对存储数据

     

    2. 字典的定义

    • 字典用{}定义
    • 键值对之间使用,分隔
    • 之间使用:分隔
    d = {'中国':'China','英国':'England','美国':'America'}

    3. 字典的特点 

    字典中的相当于索引,必须是唯一的

    1. d = {'中国':'China','英国':'England','美国':'America','美国':'USA'}
    2. print(d)

    运行: 

    {'中国': 'China', '英国': 'England', '美国': 'USA'}

    4. 字典增删改查

    4.1. 增加

    字典增加元素

    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. # 添加 法国
    3. d['法国'] = 'France'

    也可以通过setdefault方法添加 

    d.setdefault('法国','France')
    4.2. 删除 

    字典删除元素

    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. # 删除美国 如果键不在字典中,会报错
    3. del d['法国']

    也可以通过pop删除

    1. # pop 删除元素 并且返回删除元素的值 如果删除不存在会报错
    2. result = d.pop('法国')

    清空字典 

    1. # 清空容器中的数据 还可以继续使用
    2. d.clear()
    4.3. 修改

    修改字典中元素

    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. # 修改美国
    3. d['美国'] = 'USA'
    4.4. 查询

    查询元素

    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. # 查找中国
    3. value = d['中国']
    4. print(value)

    5. 字典遍历

    5.1. 遍历所有的键值对

    通过for循环遍历字典所有的键值对

    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. for ele in d:
    3. print(ele,d[ele])

    结果: 

    1. 中国 China
    2. 英国 England
    3. 美国 America
    5.2. 遍历所有的键 
    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. for key in d.keys():
    3. print(key)

    结果:

    1. 中国
    2. 英国
    3. 美国
    5.3. 遍历所有的值
    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. for value in d.values():
    3. print(value)

    结果:

    1. China
    2. England
    3. America
    5.4. 遍历所有的键值对
    1. d = {'中国':'China','英国':'England','美国':'America'}
    2. for key,value in d.items():
    3. print(key,value)

    结果:

    1. 中国 China
    2. 英国 England
    3. 美国 America

    6. 字典的应用场景

    使用多个键值对,存储描述一个物体的相关信息---描述更复杂的数据信息

    d = {'name':'张三','phone':'12332','age':40,'性别':'男'}

    四、slice切片

    1. 切片简介

    取一个strlisttuple的部分元素是非常常见的操作

    • 切片 译自英文单词slice,指的是一部分
    • 切片 根据 步长step 从原序列中取出一部分元素组成新序列
    • 切片适用于 字符串、列表、元组

    2. 切片的格式

    字符串[开始索引:结束索引:步长]

    包含开始索引, 不包含结束索引

    2.1. 需求
    1. string = '中华人民共和国欢迎您'
    2. 获取前三个文字
    2.2. 代码
    1. string = '中华人民共和国欢迎您'
    2. # 获取前三个文字
    3. newStr = string[0:3:1]

    步长默认为1,可以省略,如下

    newStr = string[0:3]

    开始索引为0,可以省略,如下 

    newStr = string[:3]

    如果到末尾结束,可以省略结束索引,例如取后三个字“欢迎您

    newStr = string[7:]

    3. 索引的正序和倒序

    索引分为正序和倒序

    • 正序:从左向右,0开始
    • 倒序:从右向左,-1开始

     

    3.1. 需求
    1. ss = "中华人名共和国欢迎您"
    2. 把字符串中从第一个到倒数第二个(不包含)打印出来
    3.2. 代码 
    1. ss = "中华人名共和国欢迎您"
    2. # 把字符串中从第一个到倒数第二个(不包含)打印出来
    3. # 开始位置:正序 结束位置:倒序
    4. print(ss[:-2])

    4. 步长为负数

    步长也可以为负数,代表逆序切片

    4.1. 需求
    1. ss = "中华人名共和国欢迎您"
    2. 把从角标为27(包含)倒序打印出来
    4.2. 代码
    1. ss = "中华人民共和国欢迎您"
    2. # 把从角标为2到7(包含)倒序打印出来
    3. # 欢国和共名人
    4. print(ss[7:1:-1])

    注意:步长为负,索引也应该逆序索引

     五、推导式

    推导式指的是轻量级循环创建数据的方式,对列表或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表;或用满足特定条件的元素创建子序列。

    推导式包括:

    • 列表推导式
    • 元组推导式
    • 集合推导式
    • 字典推导式

    1. 列表推导式

    列表推导式的格式:[计算公式 for循环 if判断]

    通过列表推导式快速创建[1, 11)所有数字的列表

    1. lst = [ele for ele in range(1, 11)]
    2. # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    通过列表推导式快速创建[1, 11)所有偶数的列表

    1. lst = [ele for ele in range(1, 11) if ele % 2 == 0]
    2. # [2, 4, 6, 8, 10]

    通过列表推导式快速创建[1, 11)所有偶数的平方的列表

    1. lst = [ele ** 2 for ele in range(1, 11) if ele % 2 == 0]
    2. # [4, 16, 36, 64, 100]

    2. 元组推导式 

    元组推导式的格式:(计算公式 for循环 if判断),其他与列表推导式一致

    tp  =(ele for ele in range(1, 11))

    3. 集合推导式

    集合推导式的格式:{计算公式 for循环 if判断},其他与列表推导式一致

    s = {ele for ele in range(1, 11)}

    4. 字典推导式

    d = {key:value for key, value in zip(range(1,10),range(21,30))}

    zip(..., ...)range(1,10)range(21,30)里的每个元素一一组合成元组 

    1. (1, 21)
    2. (2, 22)
    3. (3, 23)
    4. ...
    5. (8, 28)
    6. (9, 29)

    再把这些元组打包成一个可迭代对象。

    5. 推导式练习

    5.1. 需求
    1. 请写出一段 Python 代码实现分组一个 list 里面的元素
    2. 比如 [1,2,3,...100] 变成 [[1,2,3],[4,5,6]....[100]]
    5.2. 分析
    需要将列表中三个元素一组分隔,剩下的最后一组,其实就是对列表进行切片操作
    5.3. 代码
    1. # 创建列表
    2. lst = [ele for ele in range(1, 101)]
    3. # 切片 0:3 3:6 6:9
    4. newL = [lst[ele:ele + 3] for ele in range(0, len(lst)) if ele % 3 == 0]
    5. print(newL)

     六、高级变量类型的公共语法

    1. 内置函数

    高级变量类型有一些公共的内置函数,如下

    len 长度
    1. str = 'hello'
    2. print(len(str))

    结果:

    5
    del 删除
    1. lst = [1,2,3]
    2. del lst[0]
    3. print(lst)

    结果:

    [2,3]

    2. 运算符

     

    2.1. innot in
    1. str = 'hello'
    2. # h是否在str中
    3. result = 'h' in str
    4. print(result)
    5. result = 'h' not in str
    6. print(result)

    结果:

    1. True
    2. False
    2.2. +合并

    只有字符串、列表、元组可以合并

    1. # 字符串
    2. str1 = 'hello'
    3. str2 = 'world'
    4. str = str1 + str2

    字符串

    1. # 字符串
    2. str1 = 'hello'
    3. str2 = 'world'
    4. str = str1 + str2

    列表

    1. lst1 = [1,2,3]
    2. lst2 = [4,5,6]
    3. lst = lst1 + lst2

    元组

    1. t1 = (1,2,3)
    2. t2 = (4,5,6)
    3. t = t1 + t2
    2.3. * 重复

    只有字符串、列表、元组可以

    1. str = 'hello'
    2. print(str*3)
    3. l = [1,2,3]
    4. print(l * 3)
    5. t = (1,2,3)
    6. print(t * 3)

    结果:

    1. hellohellohello
    2. [1, 2, 3, 1, 2, 3, 1, 2, 3]
    3. [1, 2, 3, 1, 2, 3, 1, 2, 3]

     七、综合练习1-1

    字符串逆序统计

    需求:
    完成字符串的逆序以及统计
    设计一个程序,要求只能输入长度低于31的字符串,否则提示用户重新输入
    打印如下内容:
    1. --------------------------------------------
    2. 您输入的字符串: zhongshanshan
    3. 长度: 13
    4. 逆序后为: nahsnahsgnohz
    5. 字符统计结果: z:1 h:3 o:1 n:3 g:1 s:2 a:2
    6. --------------------------------------------
    分析 
    1. 1. 输入字符串(while循环)
    2. 2. 字符串长度小于31位,否则提示重新输入
    3. 3. 您输入的字符串: ...
    4. 4. 长度: ...
    5. 5. 逆序后为: ... (切片)
    6. 6. 字符统计结果: ...(afsfdsf) a:1 f:3 s:2 d:1
    代码
    1. while True:
    2. # 1.输入字符串(while循环)
    3. str = input('请输入字符串:')
    4. # 2.字符串长度小于31位,否则提示重新输入
    5. if len(str) >= 31:
    6. print('不能超过31位,请重新输入')
    7. continue
    8. # 跳出循环
    9. break
    10. print('输入正确')
    11. print("--------------------------------------------")
    12. # 3.您输入的字符串: ...
    13. print('您输入的字符串:%s' % str)
    14. # 4.长度: ...
    15. print('长度:%d' % len(str))
    16. # 5.逆序后为: ... (切片)
    17. newStr = str[::-1]
    18. print('逆序后为:%s' % newStr)
    19. # 6.字符统计结果: ...(afsfadsf) a:1 f:3 s:2 d:1
    20. # 1.字典 保存结果 {}
    21. resultDict = {}
    22. for ele in str:
    23. if ele not in resultDict:
    24. # 2. 如果字典中没有这个a, 把a添加进去 {'a':1}
    25. resultDict[ele] = 1
    26. else:
    27. # 3.字典中有a 将元素个数+1
    28. resultDict[ele] += 1
    29. print('字符统计结果:{}'.format(resultDict))
    30. print("--------------------------------------------")

     八、面向对象

    1. 面向对象和面向过程思想

    面向对象面向过程都是一种编程思想,就是解决问题的思路

    • 面向过程:POP(Procedure Oriented Programming)面向过程语言代表是c语言
    • 面向对象:OOP(Object Oriented Programming)常见的面向对象语言包括:java c++ go python koltin

    通过面向对象的方式,我们不再关注具体的步骤,而是将问题抽象为对象和它们之间的交互。我们可以直接调用对象的方法来实现功能,而无需显式指定每个步骤。

    面向过程强调按照步骤执行操作,而面向对象强调通过定义和操作对象来解决问题。

    在面向对象的编程中,我们将问题抽象为对象的集合,这些对象具有属性和行为,并通过对象之间的交互来实现功能。这种抽象和交互的方式使得面向对象编程更加灵活、可维护和可扩展。

    接下来我们看同一个问题,面向过程和面向对象是怎么解决的?

     

    1.1. 面向过程编程的贪吃蛇游戏

    在面向过程编程中,贪吃蛇游戏可能会以以下方式实现:

    1. 定义蛇的初始位置、长度、方向等变量。
    2. 创建一个表示游戏区域的二维数组。
    3. 在游戏循环中,根据用户输入改变蛇的方向。
    4. 更新蛇的位置,根据当前方向向前移动一格。
    5. 检查蛇是否吃到食物,如果是,则增加蛇的长度。
    6. 检查蛇是否撞到边界或自己的身体,如果是,则游戏结束。
    7. 在游戏区域中绘制蛇和食物。
    8. 循环回到第3步,直到游戏结束。

    在面向过程的编程中,游戏的各个方面被划分为一系列的步骤和变量,通过按照特定顺序执行这些步骤来控制游戏的逻辑和状态。

    1.2. 面向对象编程的贪吃蛇游戏

    现在,让我们看看如何使用面向对象编程来实现贪吃蛇游戏。

    1. 创建一个Snake类,具有属性(例如位置、颜色、长度、方向)和方法(例如移动、吃食物)。
    2. 创建一个Food类,具有属性(例如位置、颜色)。
    3. 创建一个Game类,它包含一个或多个蛇对象和一个或多个食物对象,以及游戏区域等属性。Game类还具有控制游戏逻辑的方法,例如更新游戏状态和绘制游戏界面。
    4. 在游戏循环中,通过调用Game类的方法来控制游戏的进行,例如根据用户输入改变蛇的方向,更新蛇的位置,检查碰撞等。
    5. 在游戏界面中,通过调用绘图方法来绘制蛇和食物。

    在面向对象编程中,贪吃蛇游戏被视为一组对象的交互。各个对象封装了游戏的状态和行为,并通过对象之间的消息传递来实现功能。这种对【对象Object】的抽象和交互使得游戏逻辑更清晰、可维护性更高,并且可以轻松地扩展和修改游戏的功能。

    1.3. 面向对象的总结
    • 面向对象,强调的是对象(实体)
    • 面向对象是一种思想,更加符合人的思维习惯
    • 面向对象使复杂的问题简单化了
    • 面向对象的出现,让曾经在过程的执行者,变成了对象的指挥者

    2. 类和对象

    类和对象是面向对象非常重要的概念

    • 类是描述了一种类型(相当于图纸)
    • 对象是这个类型的具体实现(相当于图纸具体实现)

    思考:

    旺财和狗,哪个是类,哪个是对象?

    答案:

    狗是一个类型,属于类

    旺财是狗的实现,属于对象

    类和对象的关系

    类就是制造图纸,只有一个。对象是类的实体,会产生多个

     

    定义类和创建对象 

    类的定义格式:

    1. class 类名:
    2. pass

    创建对象

    对象名 = 类名()

    代码演示:

    1. # 定义类
    2. class Person:
    3. pass
    4. # 创建对象
    5. p1 = Person()

    3. 类的组成

    类可以描述世间万物,类都需要有类名,也应该具备一些属性行为

    • 类的关键字:class
    • 类的名称:类名
    • 类的属性:一组数据
    • 类的方法:允许进行操作的方法(行为)

    人(Person)类应该具备什么属性和行为呢?

    • 属性:姓名(name) 、年纪(age)
    • 方法:吃(eat)、跑(run)、说话(say)
    3.1. 成员属性

    成员属性的定义需要在初始化方法__init__方法下定义

    格式:

    1. def __init__(self):
    2. self.属性 = 属性值

    举例:

    1. class Person:
    2. def __init__(self, name, age):
    3. # 成员属性
    4. self.name = name
    5. self.age = age
    6. # 创建对象
    7. p = Person('张三', 30)
    8. # 访问成员属性
    9. print(p.name)
    10. print(p.age)

    在创建对象时,属性值可以由外部传进来,也可以在初始化方法里设置为任意值

    3.2. 成员方法

    成员方法的定义格式为 def 函数名(self):

    1. class Person:
    2. # 定义成员方法 say_hello
    3. def say_hello(self):
    4. print('hello')
    5. # 定义成员方法run
    6. def run(self):
    7. print('跑')
    8. # 创建对象
    9. p = Person()
    10. # 调用成员方法
    11. p.say_hello()

    注意:

    成员方法都会默认有参数self,调用的时候不需要传递self

    九、 特殊方法和参数

    1. 成员方法的self参数

    成员方法中self表示调用该方法的对象。
    对象调用⽅法时,python解释器会把这个对象作为第⼀个参数传递给⽅法
    通过self也可以获取对象的属性,调用对象的其它成员方法

    1. class Person:
    2. def __init__(self, name, age):
    3. # 定义成员属性
    4. self.name = name
    5. self.age = age
    6. def say_hello(self):
    7. # 通过self访问成员属性
    8. print(self.name)
    9. # 对象
    10. p = Person('张三', 30)
    11. p.say_hello()

    2. __init__方法

    __init__是一个内置的方法
    对象创建的时候就会自动执行__init__方法

    1. # 定义类
    2. class Person:
    3. def __init__(self):
    4. print('执行了init方法')
    5. # 创建对象
    6. p1 = Person()
    7. p2 = Person()

    运行程序,输出:

    1. 执行了init方法
    2. 执行了init方法

    一旦创建了该类的对象就会执行__init__方法

    3. __str__方法

    __str__也是类的内置方法

    用于将对象转化为适于人阅读的形式

    先看一段代码:

    1. class Person:
    2. def __init__(self,name,age):
    3. # 成员属性
    4. self.name = name
    5. self.age = age
    6. # 创建对象
    7. p1 = Person('张三',30)
    8. p2 = Person('李四',40)
    9. print(p1)
    10. print(p2)

    创建了两个对象,输出两个对象

    结果:

    1. <__main__.Person object at 0x03769D10>
    2. <__main__.Person object at 0x03769FD0>

    从结果中我们并不能区分出到底哪个是属于p1,哪个是属于p2

    可以通过__str__提取对象的主要特征用于区分不同的对象

    1. class Person:
    2. def __init__(self,name,age):
    3. # 成员属性
    4. self.name = name
    5. self.age = age
    6. def __str__(self):
    7. '''
    8. 以字符串输出对象,把对象变成我们能够读懂的形式输出出来
    9. :return:
    10. '''
    11. return 'name:{}, age:{}'.format(self.name,self.age)
    12. # 创建对象
    13. p1 = Person('张三',30)
    14. p2 = Person('李四',40)
    15. print(p1)
    16. print(p2)

     输出结果:

    1. name:张三, age:30
    2. name:李四, age:40

    我们从结果中很容易就区分出两个对象的不同 

    十、私有化

    属性或者方法设置为不能在外部访问,就是私有化

    私有化包括:属性私有化方法私有化

    1. 属性私有化

    属性私有化格式,注意是两个下划线__
    self.__属性名 = 属性值

    1. class Circle:
    2. def __init__(self,radius):
    3. # 半径
    4. self.radius = radius
    5. # 私有化圆周率属性
    6. self.__PI = 3.1415926
    7. def perimeter(self):
    8. '''
    9. 求圆的周长
    10. :return: 圆的周长
    11. '''
    12. return 2 * self.__PI * self.radius

    私有化作用:保证类中数据安全

    2. 方法私有化

    方法的私有化方式和属性私有化方式一样

    1. class Person:
    2. def __say_hello(self):
    3. print('hello')

    十一、面向对象三大特征

    面向对象三大特征是:


    ●封装 (Encapsulation)
    ●继承 (Inheritance)
    ●多态 (Polymorphism)


    1.封装


    封装就是隐藏内部实现的细节,只保留功能接口
    需求
    定义一个洗衣机类,其中包含了打开/关闭洗衣机门、设置洗衣模式、设置马达转速、开始洗衣服等方法。
    在初始化时,需要传入品牌brand和容量capacity两个参数。洗衣机门的状态is_closed、洗衣模式__mode和马达转速motor_speed都有默认值。
    调用wash()方法时,会根据门的状态和模式来执行相应的操作,最终完成洗衣任务。
    步骤:


    1定义WashMachine类,初始化时传入品牌和容量两个参数,并设置默认值。
    2定义打开/关闭洗衣机门的方法,通过修改is_closed属性来实现。
    3定义设置洗衣模式的方法,通过修改__mode属性来实现。
    4定义设置马达转速的私有方法,通过修改motor_speed属性来实现。
    5定义开始洗衣服的方法,根据门的状态和模式来执行相应的操作,最终完成洗衣任务。
    6实例化WashMachine类,传入品牌和容量两个参数,得到一个洗衣机对象。
    7调用打开/关闭洗衣机门的方法,模拟打开/关闭洗衣机门的操作。
    8调用设置洗衣模式的方法,传入一个参数,设置洗衣模式。
    9调用开始洗衣服的方法,根据门的状态和模式来执行相应的操作,最终完成洗衣任务。

     实现:

    1. class WashMachine:
    2. def __init__(self, brand, capacity):
    3. """
    4. 初始化
    5. :param brand: 品牌
    6. :param capacity: 容量
    7. """
    8. self.brand = brand
    9. self.capacity = capacity
    10. # 是否关闭
    11. self.is_closed = False
    12. # 模式 0:未设定模式 1:轻揉模式 2:狂揉模式
    13. self.__mode = 0
    14. # 马达转速
    15. self.motor_speed = 0
    16. def open_door(self):
    17. self.is_closed = False
    18. print('打开洗衣机门')
    19. def close_door(self):
    20. self.is_closed = True
    21. print('关闭洗衣机门')
    22. def set_mode(self, new_mode):
    23. """
    24. 调节模式
    25. :param new_mode:
    26. :return:
    27. """
    28. if new_mode not in [1, 2]:
    29. print('设置模式错误')
    30. else:
    31. self.__mode = new_mode
    32. def __set_motor_speed(self, speed):
    33. """
    34. 设置马达的转速
    35. :param speed: 1000: 轻揉模式 2000:狂揉模式
    36. :return:
    37. """
    38. self.motor_speed = speed
    39. def wash(self):
    40. if not self.is_closed:
    41. # 洗衣机门是否关闭 ,没有关闭 提示
    42. print('请关闭洗衣机门,哔哔哔哔...')
    43. return
    44. elif self.__mode == 0:
    45. print('请设置模式')
    46. return
    47. # 执行下面的操作
    48. print('放水...')
    49. print('放满了...')
    50. if self.__mode == 1:
    51. print('轻揉模式, 洗内衣')
    52. # 调节马达转速
    53. self.__set_motor_speed(1000)
    54. print('马达转速:{}'.format(self.motor_speed))
    55. print('开始洗...')
    56. elif self.__mode == 2:
    57. print('狂揉模式, 洗外套')
    58. # 调节马达抓霉素
    59. self.__set_motor_speed(2000)
    60. print('马达转速:{}'.format(self.motor_speed))
    61. print('开始洗...')
    62. print('洗完了')
    63. machine = WashMachine('海尔', 10)
    64. machine.open_door()
    65. machine.close_door()
    66. machine.set_mode(2)
    67. machine.wash()

    封装的范围:

    1. 封装属性
    2. 封装成方法/函数
    3. 封装成类
    4. 封装模块和包

     

    2. 继承

    继承指的是一个对象直接使用另一个对象的属性或方法

    继承的格式:
    class 子类名(父类名):

    1. """------------------ 定义Person类 ------------------"""
    2. class Person:
    3. def __init__(self, name, age):
    4. self.name = name
    5. self.age = age
    6. def say_hello(self):
    7. print('hello from ', self.name)
    8. """------------------ 定义Student类继承Person ------------------"""
    9. class Student(Person):
    10. def __init__(self, name, age, height):
    11. # 调用父类的初始化方法
    12. super().__init__(name, age)
    13. # 定义自己的属性
    14. self.height = height
    15. # 创建学生类
    16. stu = Student('小明', 15, '180')
    17. # 访问属性
    18. print("name: {} age: {} height: {}".format(stu.name, stu.age, stu.height))
    19. # 调用方法
    20. stu.say_hello()

    Student类继承自Person

    可以使用Person类中定义的属性nameage以及方法say_hello

    3. 多态

    多态指的是一类事物有多种形态(一个类有多个子类)

    多态的概念依赖于继承

    中国人、美国人、非洲人都是属于Human人类的子类

    对于Human来说有多个子类就称为多态

    1. """
    2. 多态案例
    3. """
    4. # 父类
    5. class Human:
    6. def eat(self):
    7. print('人类吃饭')
    8. # 中国人
    9. class ZhHuman(Human):
    10. def eat(self):
    11. print('中国人使用筷子吃饭')
    12. # 美国人
    13. class UsHuman(Human):
    14. def eat(self):
    15. print('美国人使用刀叉吃饭')
    16. # 非洲人
    17. class AfricaHuman(Human):
    18. def eat(self):
    19. print('非洲人直接用手吃恩希玛')
    20. # 函数
    21. def someone_eat(someone):
    22. '''
    23. 接收一个具备吃eat功能的对象
    24. '''
    25. someone.eat()
    26. # 创建四个对象
    27. human = Human()
    28. zh_human = ZhHuman()
    29. us_human = UsHuman()
    30. africa_huamn = AfricaHuman()
    31. # 调用translate方法
    32. someone_eat(human)
    33. someone_eat(zh_human)
    34. someone_eat(us_human)
    35. someone_eat(africa_huamn)

    someone_eat方法需要接收具备eat功能的对象,但是由于ZhHuman USHuman AfricaHuman都具备eat功能(继承了Human)。所以也可以传递到someone_eat方法中

    4. 扩展知识

    4.1. 鸭子类型

    一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。这就是鸭子类型Duck Typing

    对于上述多态中的的someone_eat

    1. class Dog:
    2. def eat(self):
    3. print('狗吃骨头')
    4. # 函数
    5. def someone_eat(someone):
    6. '''
    7. 接收一个具备吃eat功能的对象
    8. '''
    9. someone.eat()
    10. dog = Dog()
    11. someone_eat(dog)

    someone_eat需要传递一个具备eat方法的对象,但是Dog也具备eat功能,所以也可以传递运行

    这是由于python是动态类型语言,不能像C++、Java等静态类型语言一样,限制传递的数据类型

    只要运行时发现dog对象有这个功能,就可以在函数中使用

    4.2. 多继承

    当一个类从多个父类继承属性和方法时,就称为多继承。

    多继承格式:
    class 子类(父类1,父类2...)

    下面是一个使用多继承的示例案例,展示了一个动物类和一个能飞的特性类和游泳的特性类:

    1. class Animal:
    2. def __init__(self, name):
    3. self.name = name
    4. def eat(self):
    5. print(f"{self.name} is eating.")
    6. def sleep(self):
    7. print(f"{self.name} is sleeping.")
    8. class Flyable:
    9. def fly(self):
    10. print(f"{self.name} is flying.")
    11. class Swimmable:
    12. def swim(self):
    13. print(f"{self.name} is swimming.")
    14. class Duck(Animal, Flyable, Swimmable):
    15. def __init__(self, name):
    16. super().__init__(name)
    17. duck = Duck("Donald")
    18. duck.eat() # 输出: Donald is eating.
    19. duck.sleep() # 输出: Donald is sleeping.
    20. duck.fly() # 输出: Donald is flying.
    21. duck.swim() # 输出: Donald is swimming.

     

    在上面的示例中,Animal是基类,FlyableSwimmable是特性类。Duck类通过多继承从这些类继承了属性和方法。通过调用这些继承的方法,我们可以看到Duck对象具有吃、睡、飞和游泳的行为。

    注意,在多继承的情况下,当多个父类中具有相同名称的方法时,解释器将按照方法解析顺序(Method Resolution Order,MRO)来确定使用哪个方法。在上述示例中,Python的默认MRO算法会按照类定义时的顺序来解析方法。在这个例子中,Duck类首先从Animal类继承方法,然后是Flyable类,最后是Swimmable类。

    十二、搬家具进房子

    1. 搬家具规则

    家具

    • 家具分不同的类型,并占用不同的面积
    • 输出家具信息时,显示家具的类型和家具占用的面积

    房子

    • 房子有自己的地址和占用的面积
    • 房子可以添加家具
      • 如果房子的剩余面积可以容纳家具,提示家具添加成功;
      • 否则提示添加失败
    • 输出房子信息时,可以显示房子的地址、占地面积、剩余面积
    • 查看房子中所有的家具

    2. 类的设计

    可以提取两个类:家具类Item和房子类House

    每个类具备的属性和方法如下:

     3. 家具类

    1. 1.使用 Item 类可以创建 家具对象
    2. 2.家具有两个属性:
    3. 家具类型 type:字符串
    4. 家具面积 area:整数
    5. 3.实现__str__方法
    6. 4.显示家具的 type 和 area 属性

     4. 房子类

    1. 1.使用 House 类可以创建 房子对象
    2. 2.房子有四个属性:
    3. 地址 address:字符串
    4. 房子面积 area:整数
    5. 房子剩余面积 free_area:整数,默认为房子的面积
    6. 家具列表 items:列表
    7. 3.实现__str__方法
    8. 显示房子的 address 、area、free_area 属性
    9. 4.实现add_item方法,提供item参数来添加家具
    10. 如果 可以容纳家具:
    11. 家具 加入 item属性
    12. 剩余面积 减少
    13. 如果 不能容纳家具: 提示家具添加失败

    5. 主程序逻辑

    1. 1. 创建 家具对象, 输出 家具信息
    2. 2. 创建 房子对象, 输出 房子信息
    3. 3. 房子添加家具, 输出 房子信息

    6. 代码实现 

    1. """------------------ Item家具类 ------------------"""
    2. class Item:
    3. def __init__(self, type, area):
    4. '''
    5. 创建家具类的初始化方法
    6. :param type: 家具类型
    7. :param area: 家具面积
    8. '''
    9. self.type = type
    10. self.area = area
    11. # def __str__(self):
    12. # return 'str家具类型: {},家具占用面积: {}'.format(self.type, self.area)
    13. def __repr__(self):
    14. return 'repr家具类型: {},家具占用面积: {}'.format(self.type, self.area)
    15. """------------------ House房子类 ------------------"""
    16. class House:
    17. def __init__(self, address, area):
    18. '''
    19. 房子的初始化方法
    20. :param address: 房子地址
    21. :param area: 房子面积
    22. '''
    23. self.address = address
    24. self.area = area
    25. # 剩余面积
    26. self.free_area = self.area
    27. # 家具列表
    28. self.items = []
    29. def __str__(self):
    30. return '房子地址: {},占地面积: {},剩余面积: {}'.format(self.address, self.area, self.free_area)
    31. def add_item(self, item):
    32. """
    33. 添加家具到房子中
    34. :param item: 家具类Item的实例
    35. :return:
    36. """
    37. if self.free_area >= item.area:
    38. # 家具添加到列表中
    39. self.items.append(item)
    40. # 修改剩余面积
    41. self.free_area -= item.area
    42. # 可以添加
    43. print('添加成功')
    44. else:
    45. # 不能添加
    46. print('面积不足, 不能添加家具')
    47. # 创建家具
    48. item1 = Item('桌子', 40)
    49. item2 = Item('椅子', 10)
    50. item3 = Item('家庭影院', 80)
    51. print(item1)
    52. print(item2)
    53. print(item3)
    54. # 创建房子
    55. house = House('深圳湾一号', 100)
    56. # 打印家具
    57. print(house)
    58. print("---------------------------------------------")
    59. # 添加家具
    60. house.add_item(item1)
    61. house.add_item(item2)
    62. house.add_item(item3)
    63. print(house)
    64. print("所有家具: ", house.items)

    扩展:

    • __str__方法返回一个友好的、可读性较高的字符串,主要用于用户可见的输出,强调可读性和易理解性。常用于直接print对象。
    • __repr__方法返回一个准确和详细的字符串,主要用于开发和调试过程中,强调准确性和完整性。常用于打印listsetdict等内部的所有对象

     

  • 相关阅读:
    路径该不该加斜杆呢
    12月2日(第四天)
    MySQL实现事务隔离的原理
    领域驱动设计:领域模型与代码模型的一致性
    Forescout宣布任命Rik Ferguson为安全情报副总裁
    【好玩】如何在github主页放一条贪吃蛇
    【QT】Qt的随身笔记(持续更新...)
    基于html5的网上书店系统
    iOS——引用计数(一)
    项目训练营第四天
  • 原文地址:https://blog.csdn.net/liyimindbq/article/details/138168275