字符串就是一串字符,是编程语言中表示文本的数据类型
Python中可以使用一对双引号或者一对单引号定义字符串
- str1 = 'hello'
- str2 = "hello"
和列表一样,字符串也是通过索引获取元素
- str = "hello"
- # 获取第三个元素
- ele = str[2] # l
可以通过for循环遍历字符串
- str = 'hello'
- for ele in str:
- print(ele)

4.3. 切割
需求
- 用户名和密码格式校验程序
- 要求从键盘输入用户名和密码,分别校验格式是否符合规则
- 如果符合,打印
用户名合法,密码合法- 如果不符合,打印出不符合的原因,并提示重新输入
- 用户名长度
6-20,用户名必须以字母开头- 密码长度至少
6位,不能为纯数字,不能有空格
分析
1.从键盘输入用户名(需要while循环)
2.长度6-20
3.必须字母开头4.输入密码(while循环)
5.密码长度至少6位
6.不能为纯数字
7.不能有空格
实现
- while True:
- # 1.从键盘输入用户名(需要while循环)
- name = input('请输入用户名:')
- # 2.长度6-20
- if not (len(name) >= 6 and len(name) <= 20):
- print('用户名必须6到20位')
- continue
- # 3.必须字母开头 ab A-Z
- # 获取第一个字母 是否是a-z A-Z a
- ele = name[0]
- if not ele.isalpha():
- print('用户名第一个必须为字母')
- continue
-
- # 用户名满足
- print('用户名合法')
- break
-
- # 4.输入密码(while循环)
- while True:
- pwd = input('请输入密码')
- # 5.密码长度至少6位
- if len(pwd) < 6:
- print('密码长度至少为6位')
- continue
- # 6.不能为纯数字
- if pwd.isdecimal():
- print('密码不能为纯数字')
- continue
- # 7.不能有空格
- # ' 张 三 '
- if ' ' in pwd:
- print('密码不能有空格')
- continue
- print('密码合法')
- break
扩展
isalpha()字符串中所有元素都是字母,则返回Trueisdecimal()字符串中都是数字,则返回True
set被称为集合,是无序的,并且集合中的元素是唯一的
s = {'张三','李四','王五'}
集合是无序的
- s = {'张三','李四','王五'}
- print(s)
结果:
{'王五', '张三', '李四'}
集合元素唯一
- s = {'张三','李四','王五','张三'}
- print(s)
结果:
{'李四', '张三', '王五'}
通过for循环遍历集合中的元素
- s = {'张三','李四','王五'}
- # 遍历集合
- for ele in s:
- print(ele)
集合可以通过add方法添加元素
- s = {'张三','李四','王五'}
- # # 添加赵六 add
- s.add('赵六')
remove删除,如果有 直接删除,如果没有 程序报错
- s = {'张三','李四','王五'}
- # 删除张三
- s.remove('张三')
pop删除,随机删除集合中的元素并返回,如果集合中没有元素,则程序报错
- s = {'张三','李四','王五'}
- # pop 随机删除
- print(s.pop())
discard删除,元素存在则直接删除,如果元素不存在,则不做任何操作
- s = {'张三','李四','王五'}
- # discard 删除元素 如果元素不存在,不做任何处理
- s.discard('林青霞')
dictionary(字典) 是 除列表以外 Python 之中 最灵活 的数据类型,类型为dict
- 字典同样可以用来存储多个数据
- 字典使用键值对存储数据
- 字典用
{}定义- 键值对之间使用
,分隔- 键和值之间使用
:分隔
d = {'中国':'China','英国':'England','美国':'America'}
字典中的键相当于索引,必须是唯一的
- d = {'中国':'China','英国':'England','美国':'America','美国':'USA'}
- print(d)
运行:
{'中国': 'China', '英国': 'England', '美国': 'USA'}
字典增加元素
- d = {'中国':'China','英国':'England','美国':'America'}
- # 添加 法国
- d['法国'] = 'France'
也可以通过setdefault方法添加
d.setdefault('法国','France')
字典删除元素
- d = {'中国':'China','英国':'England','美国':'America'}
- # 删除美国 如果键不在字典中,会报错
- del d['法国']
也可以通过pop删除
- # pop 删除元素 并且返回删除元素的值 如果删除不存在会报错
- result = d.pop('法国')
清空字典
- # 清空容器中的数据 还可以继续使用
- d.clear()
修改字典中元素
- d = {'中国':'China','英国':'England','美国':'America'}
- # 修改美国
- d['美国'] = 'USA'
查询元素
- d = {'中国':'China','英国':'England','美国':'America'}
- # 查找中国
- value = d['中国']
- print(value)
通过for循环遍历字典所有的键值对
- d = {'中国':'China','英国':'England','美国':'America'}
-
- for ele in d:
- print(ele,d[ele])
结果:
- 中国 China
- 英国 England
- 美国 America
- d = {'中国':'China','英国':'England','美国':'America'}
- for key in d.keys():
- print(key)
结果:
- 中国
- 英国
- 美国
- d = {'中国':'China','英国':'England','美国':'America'}
-
- for value in d.values():
- print(value)
结果:
- China
- England
- America
- d = {'中国':'China','英国':'England','美国':'America'}
- for key,value in d.items():
- print(key,value)
结果:
- 中国 China
- 英国 England
- 美国 America
使用多个键值对,存储描述一个物体的相关信息---描述更复杂的数据信息
d = {'name':'张三','phone':'12332','age':40,'性别':'男'}
取一个str、list、tuple的部分元素是非常常见的操作
- 切片 译自英文单词
slice,指的是一部分- 切片 根据 步长
step从原序列中取出一部分元素组成新序列- 切片适用于 字符串、列表、元组
字符串[开始索引:结束索引:步长]包含开始索引, 不包含结束索引
- string = '中华人民共和国欢迎您'
- 获取前三个文字
- string = '中华人民共和国欢迎您'
- # 获取前三个文字
- newStr = string[0:3:1]
步长默认为1,可以省略,如下
newStr = string[0:3]
开始索引为0,可以省略,如下
newStr = string[:3]
如果到末尾结束,可以省略结束索引,例如取后三个字“欢迎您”
newStr = string[7:]
索引分为正序和倒序
- 正序:从左向右,
0开始- 倒序:从右向左,
-1开始
- ss = "中华人名共和国欢迎您"
- 把字符串中从第一个到倒数第二个(不包含)打印出来
- ss = "中华人名共和国欢迎您"
- # 把字符串中从第一个到倒数第二个(不包含)打印出来
- # 开始位置:正序 结束位置:倒序
- print(ss[:-2])
步长也可以为负数,代表逆序切片
- ss = "中华人名共和国欢迎您"
- 把从角标为2到7(包含)倒序打印出来
- ss = "中华人民共和国欢迎您"
- # 把从角标为2到7(包含)倒序打印出来
- # 欢国和共名人
- print(ss[7:1:-1])
注意:步长为负,索引也应该逆序索引
推导式指的是轻量级循环创建数据的方式,对列表或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表;或用满足特定条件的元素创建子序列。
推导式包括:
- 列表推导式
- 元组推导式
- 集合推导式
- 字典推导式
列表推导式的格式:[计算公式 for循环 if判断]
通过列表推导式快速创建[1, 11)所有数字的列表
- lst = [ele for ele in range(1, 11)]
- # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
通过列表推导式快速创建[1, 11)所有偶数的列表
- lst = [ele for ele in range(1, 11) if ele % 2 == 0]
- # [2, 4, 6, 8, 10]
通过列表推导式快速创建[1, 11)所有偶数的平方的列表
- lst = [ele ** 2 for ele in range(1, 11) if ele % 2 == 0]
- # [4, 16, 36, 64, 100]
元组推导式的格式:(计算公式 for循环 if判断),其他与列表推导式一致
tp =(ele for ele in range(1, 11))
集合推导式的格式:{计算公式 for循环 if判断},其他与列表推导式一致
s = {ele for ele in range(1, 11)}
d = {key:value for key, value in zip(range(1,10),range(21,30))}
zip(..., ...)将range(1,10)和range(21,30)里的每个元素一一组合成元组
- (1, 21)
- (2, 22)
- (3, 23)
- ...
- (8, 28)
- (9, 29)
再把这些元组打包成一个可迭代对象。
- 请写出一段 Python 代码实现分组一个 list 里面的元素
- 比如 [1,2,3,...100] 变成 [[1,2,3],[4,5,6]....[100]]
需要将列表中三个元素一组分隔,剩下的最后一组,其实就是对列表进行切片操作
- # 创建列表
- lst = [ele for ele in range(1, 101)]
-
- # 切片 0:3 3:6 6:9
- newL = [lst[ele:ele + 3] for ele in range(0, len(lst)) if ele % 3 == 0]
- print(newL)
高级变量类型有一些公共的内置函数,如下

- str = 'hello'
- print(len(str))
结果:
5
- lst = [1,2,3]
- del lst[0]
- print(lst)
结果:
[2,3]
in和not in- str = 'hello'
- # h是否在str中
- result = 'h' in str
- print(result)
- result = 'h' not in str
- print(result)
结果:
- True
- False
+合并只有字符串、列表、元组可以合并
- # 字符串
- str1 = 'hello'
- str2 = 'world'
- str = str1 + str2
字符串
- # 字符串
- str1 = 'hello'
- str2 = 'world'
- str = str1 + str2
列表
- lst1 = [1,2,3]
- lst2 = [4,5,6]
- lst = lst1 + lst2
元组
- t1 = (1,2,3)
- t2 = (4,5,6)
- t = t1 + t2
* 重复只有字符串、列表、元组可以
- str = 'hello'
- print(str*3)
-
- l = [1,2,3]
- print(l * 3)
-
- t = (1,2,3)
- print(t * 3)
结果:
- hellohellohello
- [1, 2, 3, 1, 2, 3, 1, 2, 3]
- [1, 2, 3, 1, 2, 3, 1, 2, 3]
- --------------------------------------------
- 您输入的字符串: zhongshanshan
- 长度: 13
- 逆序后为: nahsnahsgnohz
- 字符统计结果: z:1 h:3 o:1 n:3 g:1 s:2 a:2
- --------------------------------------------
- 1. 输入字符串(while循环)
- 2. 字符串长度小于31位,否则提示重新输入
- 3. 您输入的字符串: ...
- 4. 长度: ...
- 5. 逆序后为: ... (切片)
- 6. 字符统计结果: ...(afsfdsf) a:1 f:3 s:2 d:1
- while True:
- # 1.输入字符串(while循环)
- str = input('请输入字符串:')
- # 2.字符串长度小于31位,否则提示重新输入
- if len(str) >= 31:
- print('不能超过31位,请重新输入')
- continue
- # 跳出循环
- break
- print('输入正确')
- print("--------------------------------------------")
- # 3.您输入的字符串: ...
- print('您输入的字符串:%s' % str)
- # 4.长度: ...
- print('长度:%d' % len(str))
- # 5.逆序后为: ... (切片)
- newStr = str[::-1]
- print('逆序后为:%s' % newStr)
- # 6.字符统计结果: ...(afsfadsf) a:1 f:3 s:2 d:1
- # 1.字典 保存结果 {}
- resultDict = {}
- for ele in str:
- if ele not in resultDict:
- # 2. 如果字典中没有这个a, 把a添加进去 {'a':1}
- resultDict[ele] = 1
- else:
- # 3.字典中有a 将元素个数+1
- resultDict[ele] += 1
- print('字符统计结果:{}'.format(resultDict))
- print("--------------------------------------------")
面向对象和面向过程都是一种编程思想,就是解决问题的思路
- 面向过程:
POP(Procedure Oriented Programming)面向过程语言代表是c语言- 面向对象:
OOP(Object Oriented Programming)常见的面向对象语言包括:java c++ go python koltin
通过面向对象的方式,我们不再关注具体的步骤,而是将问题抽象为对象和它们之间的交互。我们可以直接调用对象的方法来实现功能,而无需显式指定每个步骤。
面向过程强调按照步骤执行操作,而面向对象强调通过定义和操作对象来解决问题。
在面向对象的编程中,我们将问题抽象为对象的集合,这些对象具有属性和行为,并通过对象之间的交互来实现功能。这种抽象和交互的方式使得面向对象编程更加灵活、可维护和可扩展。
接下来我们看同一个问题,面向过程和面向对象是怎么解决的?
在面向过程编程中,贪吃蛇游戏可能会以以下方式实现:
- 定义蛇的初始位置、长度、方向等变量。
- 创建一个表示游戏区域的二维数组。
- 在游戏循环中,根据用户输入改变蛇的方向。
- 更新蛇的位置,根据当前方向向前移动一格。
- 检查蛇是否吃到食物,如果是,则增加蛇的长度。
- 检查蛇是否撞到边界或自己的身体,如果是,则游戏结束。
- 在游戏区域中绘制蛇和食物。
- 循环回到第3步,直到游戏结束。
在面向过程的编程中,游戏的各个方面被划分为一系列的步骤和变量,通过按照特定顺序执行这些步骤来控制游戏的逻辑和状态。
现在,让我们看看如何使用面向对象编程来实现贪吃蛇游戏。
- 创建一个
Snake类,具有属性(例如位置、颜色、长度、方向)和方法(例如移动、吃食物)。- 创建一个
Food类,具有属性(例如位置、颜色)。- 创建一个
Game类,它包含一个或多个蛇对象和一个或多个食物对象,以及游戏区域等属性。Game类还具有控制游戏逻辑的方法,例如更新游戏状态和绘制游戏界面。- 在游戏循环中,通过调用Game类的方法来控制游戏的进行,例如根据用户输入改变蛇的方向,更新蛇的位置,检查碰撞等。
- 在游戏界面中,通过调用绘图方法来绘制蛇和食物。
在面向对象编程中,贪吃蛇游戏被视为一组对象的交互。各个对象封装了游戏的状态和行为,并通过对象之间的消息传递来实现功能。这种对【对象Object】的抽象和交互使得游戏逻辑更清晰、可维护性更高,并且可以轻松地扩展和修改游戏的功能。
- 面向对象,强调的是对象(实体)
- 面向对象是一种思想,更加符合人的思维习惯
- 面向对象使复杂的问题简单化了
- 面向对象的出现,让曾经在过程的执行者,变成了对象的指挥者
类和对象是面向对象非常重要的概念
- 类是描述了一种类型(相当于图纸)
- 对象是这个类型的具体实现(相当于图纸具体实现)
思考:
旺财和狗,哪个是类,哪个是对象?
答案:
狗是一个类型,属于类
旺财是狗的实现,属于对象
类和对象的关系
类就是制造图纸,只有一个。对象是类的实体,会产生多个
定义类和创建对象
类的定义格式:
- class 类名:
- pass
创建对象
对象名 = 类名()
代码演示:
- # 定义类
- class Person:
- pass
- # 创建对象
- p1 = Person()
类可以描述世间万物,类都需要有类名,也应该具备一些属性和行为
- 类的关键字:
class- 类的名称:类名
- 类的属性:一组数据
- 类的方法:允许进行操作的方法(行为)
人(Person)类应该具备什么属性和行为呢?
- 属性:姓名(
name) 、年纪(age)- 方法:吃(
eat)、跑(run)、说话(say)
成员属性的定义需要在初始化方法__init__方法下定义
格式:
- def __init__(self):
- self.属性 = 属性值
举例:
- class Person:
- def __init__(self, name, age):
- # 成员属性
- self.name = name
- self.age = age
-
- # 创建对象
- p = Person('张三', 30)
- # 访问成员属性
- print(p.name)
- print(p.age)
在创建对象时,属性值可以由外部传进来,也可以在初始化方法里设置为任意值
成员方法的定义格式为 def 函数名(self):
- class Person:
-
- # 定义成员方法 say_hello
- def say_hello(self):
- print('hello')
-
- # 定义成员方法run
- def run(self):
- print('跑')
-
- # 创建对象
- p = Person()
- # 调用成员方法
- p.say_hello()
注意:
成员方法都会默认有参数
self,调用的时候不需要传递self
self参数成员方法中self表示调用该方法的对象。
对象调用⽅法时,python解释器会把这个对象作为第⼀个参数传递给⽅法
通过self也可以获取对象的属性,调用对象的其它成员方法
- class Person:
- def __init__(self, name, age):
- # 定义成员属性
- self.name = name
- self.age = age
-
- def say_hello(self):
- # 通过self访问成员属性
- print(self.name)
-
-
- # 对象
- p = Person('张三', 30)
- p.say_hello()
__init__方法__init__是一个内置的方法
当对象创建的时候就会自动执行__init__方法
- # 定义类
- class Person:
- def __init__(self):
- print('执行了init方法')
-
- # 创建对象
- p1 = Person()
- p2 = Person()
运行程序,输出:
- 执行了init方法
- 执行了init方法
一旦创建了该类的对象就会执行__init__方法
__str__方法__str__也是类的内置方法
用于将对象转化为适于人阅读的形式
先看一段代码:
- class Person:
- def __init__(self,name,age):
- # 成员属性
- self.name = name
- self.age = age
-
- # 创建对象
- p1 = Person('张三',30)
- p2 = Person('李四',40)
- print(p1)
- print(p2)
创建了两个对象,输出两个对象
结果:
- <__main__.Person object at 0x03769D10>
- <__main__.Person object at 0x03769FD0>
从结果中我们并不能区分出到底哪个是属于p1,哪个是属于p2
可以通过__str__提取对象的主要特征用于区分不同的对象
- class Person:
- def __init__(self,name,age):
- # 成员属性
- self.name = name
- self.age = age
-
- def __str__(self):
- '''
- 以字符串输出对象,把对象变成我们能够读懂的形式输出出来
- :return:
- '''
- return 'name:{}, age:{}'.format(self.name,self.age)
-
- # 创建对象
- p1 = Person('张三',30)
- p2 = Person('李四',40)
- print(p1)
- print(p2)
输出结果:
- name:张三, age:30
- name:李四, age:40
我们从结果中很容易就区分出两个对象的不同
将属性或者方法设置为不能在外部访问,就是私有化
私有化包括:属性私有化、方法私有化
属性私有化格式,注意是两个下划线__self.__属性名 = 属性值
- class Circle:
- def __init__(self,radius):
- # 半径
- self.radius = radius
- # 私有化圆周率属性
- self.__PI = 3.1415926
-
-
- def perimeter(self):
- '''
- 求圆的周长
- :return: 圆的周长
- '''
- return 2 * self.__PI * self.radius
私有化作用:保证类中数据安全
方法的私有化方式和属性私有化方式一样
- class Person:
- def __say_hello(self):
- print('hello')
面向对象三大特征是:
●封装 (Encapsulation)
●继承 (Inheritance)
●多态 (Polymorphism)
封装就是隐藏内部实现的细节,只保留功能接口
需求
定义一个洗衣机类,其中包含了打开/关闭洗衣机门、设置洗衣模式、设置马达转速、开始洗衣服等方法。
在初始化时,需要传入品牌brand和容量capacity两个参数。洗衣机门的状态is_closed、洗衣模式__mode和马达转速motor_speed都有默认值。
调用wash()方法时,会根据门的状态和模式来执行相应的操作,最终完成洗衣任务。
步骤:
1定义WashMachine类,初始化时传入品牌和容量两个参数,并设置默认值。
2定义打开/关闭洗衣机门的方法,通过修改is_closed属性来实现。
3定义设置洗衣模式的方法,通过修改__mode属性来实现。
4定义设置马达转速的私有方法,通过修改motor_speed属性来实现。
5定义开始洗衣服的方法,根据门的状态和模式来执行相应的操作,最终完成洗衣任务。
6实例化WashMachine类,传入品牌和容量两个参数,得到一个洗衣机对象。
7调用打开/关闭洗衣机门的方法,模拟打开/关闭洗衣机门的操作。
8调用设置洗衣模式的方法,传入一个参数,设置洗衣模式。
9调用开始洗衣服的方法,根据门的状态和模式来执行相应的操作,最终完成洗衣任务。
实现:
- class WashMachine:
- def __init__(self, brand, capacity):
- """
- 初始化
- :param brand: 品牌
- :param capacity: 容量
- """
- self.brand = brand
- self.capacity = capacity
- # 是否关闭
- self.is_closed = False
- # 模式 0:未设定模式 1:轻揉模式 2:狂揉模式
- self.__mode = 0
- # 马达转速
- self.motor_speed = 0
-
- def open_door(self):
- self.is_closed = False
- print('打开洗衣机门')
-
- def close_door(self):
- self.is_closed = True
- print('关闭洗衣机门')
-
- def set_mode(self, new_mode):
- """
- 调节模式
- :param new_mode:
- :return:
- """
- if new_mode not in [1, 2]:
- print('设置模式错误')
- else:
- self.__mode = new_mode
-
- def __set_motor_speed(self, speed):
- """
- 设置马达的转速
- :param speed: 1000: 轻揉模式 2000:狂揉模式
- :return:
- """
- self.motor_speed = speed
-
- def wash(self):
- if not self.is_closed:
- # 洗衣机门是否关闭 ,没有关闭 提示
- print('请关闭洗衣机门,哔哔哔哔...')
- return
- elif self.__mode == 0:
- print('请设置模式')
- return
-
- # 执行下面的操作
- print('放水...')
- print('放满了...')
- if self.__mode == 1:
- print('轻揉模式, 洗内衣')
- # 调节马达转速
- self.__set_motor_speed(1000)
- print('马达转速:{}'.format(self.motor_speed))
- print('开始洗...')
- elif self.__mode == 2:
- print('狂揉模式, 洗外套')
- # 调节马达抓霉素
- self.__set_motor_speed(2000)
- print('马达转速:{}'.format(self.motor_speed))
- print('开始洗...')
-
- print('洗完了')
-
-
- machine = WashMachine('海尔', 10)
- machine.open_door()
- machine.close_door()
- machine.set_mode(2)
- machine.wash()
封装的范围:
- 封装属性
- 封装成方法/函数
- 封装成类
- 封装模块和包
继承指的是一个对象直接使用另一个对象的属性或方法
继承的格式:class 子类名(父类名):
- """------------------ 定义Person类 ------------------"""
-
-
- class Person:
- def __init__(self, name, age):
- self.name = name
- self.age = age
-
- def say_hello(self):
- print('hello from ', self.name)
-
-
- """------------------ 定义Student类继承Person ------------------"""
-
-
- class Student(Person):
- def __init__(self, name, age, height):
- # 调用父类的初始化方法
- super().__init__(name, age)
- # 定义自己的属性
- self.height = height
-
-
- # 创建学生类
- stu = Student('小明', 15, '180')
- # 访问属性
- print("name: {} age: {} height: {}".format(stu.name, stu.age, stu.height))
- # 调用方法
- stu.say_hello()
Student类继承自Person类
可以使用Person类中定义的属性name和age以及方法say_hello
多态指的是一类事物有多种形态(一个类有多个子类)
多态的概念依赖于继承

中国人、美国人、非洲人都是属于Human人类的子类
对于Human来说有多个子类就称为多态
- """
- 多态案例
- """
- # 父类
- class Human:
- def eat(self):
- print('人类吃饭')
-
- # 中国人
- class ZhHuman(Human):
- def eat(self):
- print('中国人使用筷子吃饭')
-
- # 美国人
- class UsHuman(Human):
- def eat(self):
- print('美国人使用刀叉吃饭')
-
- # 非洲人
- class AfricaHuman(Human):
- def eat(self):
- print('非洲人直接用手吃恩希玛')
-
-
- # 函数
- def someone_eat(someone):
- '''
- 接收一个具备吃eat功能的对象
- '''
- someone.eat()
-
-
- # 创建四个对象
- human = Human()
- zh_human = ZhHuman()
- us_human = UsHuman()
- africa_huamn = AfricaHuman()
-
- # 调用translate方法
- someone_eat(human)
- someone_eat(zh_human)
- someone_eat(us_human)
- someone_eat(africa_huamn)
someone_eat方法需要接收具备eat功能的对象,但是由于ZhHuman USHuman AfricaHuman都具备eat功能(继承了Human)。所以也可以传递到someone_eat方法中
一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子。这就是鸭子类型Duck Typing
对于上述多态中的的someone_eat
- class Dog:
- def eat(self):
- print('狗吃骨头')
-
- # 函数
- def someone_eat(someone):
- '''
- 接收一个具备吃eat功能的对象
- '''
- someone.eat()
-
- dog = Dog()
- someone_eat(dog)
someone_eat需要传递一个具备eat方法的对象,但是Dog也具备eat功能,所以也可以传递运行
这是由于python是动态类型语言,不能像C++、Java等静态类型语言一样,限制传递的数据类型
只要运行时发现dog对象有这个功能,就可以在函数中使用
当一个类从多个父类继承属性和方法时,就称为多继承。
多继承格式:class 子类(父类1,父类2...)
下面是一个使用多继承的示例案例,展示了一个动物类和一个能飞的特性类和游泳的特性类:
- class Animal:
- def __init__(self, name):
- self.name = name
-
- def eat(self):
- print(f"{self.name} is eating.")
-
- def sleep(self):
- print(f"{self.name} is sleeping.")
-
-
- class Flyable:
- def fly(self):
- print(f"{self.name} is flying.")
-
-
- class Swimmable:
- def swim(self):
- print(f"{self.name} is swimming.")
-
-
- class Duck(Animal, Flyable, Swimmable):
- def __init__(self, name):
- super().__init__(name)
-
-
- duck = Duck("Donald")
- duck.eat() # 输出: Donald is eating.
- duck.sleep() # 输出: Donald is sleeping.
- duck.fly() # 输出: Donald is flying.
- duck.swim() # 输出: Donald is swimming.
在上面的示例中,Animal是基类,Flyable和Swimmable是特性类。Duck类通过多继承从这些类继承了属性和方法。通过调用这些继承的方法,我们可以看到Duck对象具有吃、睡、飞和游泳的行为。
注意,在多继承的情况下,当多个父类中具有相同名称的方法时,解释器将按照方法解析顺序(Method Resolution Order,MRO)来确定使用哪个方法。在上述示例中,Python的默认MRO算法会按照类定义时的顺序来解析方法。在这个例子中,Duck类首先从Animal类继承方法,然后是Flyable类,最后是Swimmable类。
家具
- 家具分不同的类型,并占用不同的面积
- 输出家具信息时,显示家具的类型和家具占用的面积
房子
- 房子有自己的地址和占用的面积
- 房子可以添加家具
- 如果房子的剩余面积可以容纳家具,提示家具添加成功;
- 否则提示添加失败
- 输出房子信息时,可以显示房子的地址、占地面积、剩余面积
- 查看房子中所有的家具
可以提取两个类:家具类Item和房子类House
每个类具备的属性和方法如下:

- 1.使用 Item 类可以创建 家具对象
- 2.家具有两个属性:
- 家具类型 type:字符串
- 家具面积 area:整数
- 3.实现__str__方法
- 4.显示家具的 type 和 area 属性
- 1.使用 House 类可以创建 房子对象
- 2.房子有四个属性:
- 地址 address:字符串
- 房子面积 area:整数
- 房子剩余面积 free_area:整数,默认为房子的面积
- 家具列表 items:列表
- 3.实现__str__方法
- 显示房子的 address 、area、free_area 属性
- 4.实现add_item方法,提供item参数来添加家具
- 如果 可以容纳家具:
- 家具 加入 item属性
- 剩余面积 减少
- 如果 不能容纳家具: 提示家具添加失败
- 1. 创建 家具对象, 输出 家具信息
- 2. 创建 房子对象, 输出 房子信息
- 3. 房子添加家具, 输出 房子信息
- """------------------ Item家具类 ------------------"""
- class Item:
- def __init__(self, type, area):
- '''
- 创建家具类的初始化方法
- :param type: 家具类型
- :param area: 家具面积
- '''
- self.type = type
- self.area = area
-
- # def __str__(self):
- # return 'str家具类型: {},家具占用面积: {}'.format(self.type, self.area)
-
- def __repr__(self):
- return 'repr家具类型: {},家具占用面积: {}'.format(self.type, self.area)
-
-
- """------------------ House房子类 ------------------"""
- class House:
- def __init__(self, address, area):
- '''
- 房子的初始化方法
- :param address: 房子地址
- :param area: 房子面积
- '''
- self.address = address
- self.area = area
- # 剩余面积
- self.free_area = self.area
- # 家具列表
- self.items = []
-
- def __str__(self):
- return '房子地址: {},占地面积: {},剩余面积: {}'.format(self.address, self.area, self.free_area)
-
- def add_item(self, item):
- """
- 添加家具到房子中
- :param item: 家具类Item的实例
- :return:
- """
- if self.free_area >= item.area:
- # 家具添加到列表中
- self.items.append(item)
- # 修改剩余面积
- self.free_area -= item.area
- # 可以添加
- print('添加成功')
- else:
- # 不能添加
- print('面积不足, 不能添加家具')
-
-
- # 创建家具
- item1 = Item('桌子', 40)
- item2 = Item('椅子', 10)
- item3 = Item('家庭影院', 80)
- print(item1)
- print(item2)
- print(item3)
-
- # 创建房子
- house = House('深圳湾一号', 100)
- # 打印家具
- print(house)
-
- print("---------------------------------------------")
- # 添加家具
- house.add_item(item1)
- house.add_item(item2)
- house.add_item(item3)
- print(house)
- print("所有家具: ", house.items)
扩展:
__str__方法返回一个友好的、可读性较高的字符串,主要用于用户可见的输出,强调可读性和易理解性。常用于直接__repr__方法返回一个准确和详细的字符串,主要用于开发和调试过程中,强调准确性和完整性。常用于打印list、set、dict等内部的所有对象