python安装
官网:https://www.python.org/
下载对应系统版本的python安装,完成后可以在CMD输入下面代码查看安装版本
python --version
python代码初体验
你好,世界
打开CMD,输入python并回车进入python解释器
如何判断进入python解释器?
- 屏幕左侧会出现粉色箭头>>>
如何退出python解释器? - 在python解释器中输入exit就会退出解释器界面,判断是否退出的方法:左侧粉色箭头>>>变成具体的盘符
tips: python代码必须全部使用英文标点符号
print('Hello world')
在python解释器中输入上述代码会打印输出Hello world
print('Hello python')
在python解释器中输入上述代码会打印输出Hello python
创建第一个python文件
在文件夹中右键创建一个记事本文件,把后缀名.txt改成.py
tips: 所有python文件的后缀名都是.py
在.py文件内输入以下代码并保存
print('####################')
print('#### Hello World ###')
print('####################')
在文件所在的路径打开cmd输入python 文件名.py即可打印输出以下三行代码
####################
#### Hello World ###
####################
Python开发工具
开发工具有很多,最常见的是VSCode和PyCharm等.
VSCode官网:https://code.visualstudio.com/
PyCharm官网:https://www.jetbrains.com/pycharm/
Python语法
注释
注释的作用:
- 对代码进行文字说明,方便自己和他人阅读理解;
- 临时屏蔽一段代码,让代码不执行;
Python 注释分为单行注释、多行注释两大类。
# (# 是Python中注释的写法,注释是给开发人员看的,快捷键Ctrl+/)
# (# 是单行注释,每一行前面都要加上#)
"""
三引号是多行注释,多用于文档注释函数、类说明
三引号分为三个单引号或三个双引号,用法功能是一样的
"""
字面量
字面量是指程序中,直接写在代码里、运行前就确定的常量值,就称为字面量。例如:66、3.14、"Python"、True、None、[1,2,3]。
| 字面量分类 | 细分类型 | 说明 | 示例 |
|---|---|---|---|
| 数字类型 | 整数 int | 正负整数,无小数点 | 10、-5、0 |
| 浮点数 float | 带小数点的小数 | 3.14、-0.8 | |
| 复数 complex | 数学复数,初学者了解即可 | 2+3j | |
| 布尔类型 | bool | 用于逻辑判断,仅两个取值 | True(真,等价 1)、False(假,等价 0) |
| 字符串 | str | 文本数据,单 / 双 / 三引号包裹,不可变 | '笔记'、"Hello"、"""多行文本""" |
| 空值 | NoneType | 代表无数据、空对象,唯一值 None | None |
| 数据容器 | 列表 list、元组 tuple、字典 dict、集合 set | 可以批量存放多个数据 | [1,2]、(1,2)、{"a":1} |
# 字面量的写法
print(100) # 整数(int)
print(3.14) # 浮点数(float)
print(True) # 布尔(bool)
print(False) # 布尔(bool)
print("Hello Python") # 字符串(str)
print("-------------------") # 字符串(str)
print(None) # 空值(NoneType)
# 布尔类型本质是整数类型(True=1;False=0)
print(True + 1) # 2
print(True - 1) # 0
变量
变量是程序中用来存储单个数据的容器,通常会把经常发生变化的数据存储在变量中。
定义格式:变量名 = 变量的值,例如: num = 1114.1
tips: Python是动态类型语言,在程序运行时才进行类型检查,变量的类型可以在程序运行过程中改变(一个变量可以接收不同类型的值)。
# 变量 ---> Python是动态类型的语言,一个变量是可以存储不同类型的数据的(但是项目开发中,推荐变量只存储一种类型的数据)
num = 1114.1
print(num)
num = num + 1
print(num)
num = 'OK'
print(num)
num = True
print(num)
# 案例
# 课程基础播放量为20.7万
# 每月新增播放量50万
# 请输出未来两个月每个月的播放总量
base = 20.7
incr = 50
print('未来第一个月的播放总量:',base + incr)
print('未来第二个月的播放总量:',base + incr + incr)
标识符
标识符是程序员在代码中为变量、函数、类等元素所起的名字。
命名规则:
- 只能包含字母(a-z,A-Z)、数字(0-9)、下划线( _ )
- 不能以数字开头
- 不能使用关键字:True、False、None、and、or、if、else、elif、for、while等
- 严格区分大小写,比如:age,Age,AGE是三个变量
命名规范(变量): - 见名知意
- 多个部分使用下划线连接
- 英文字母全小写
# 案例1:现有两个变量,分别为:a=10,b=20,现需要将这两个变量值交换,然后输出到控制台。
# 方法一:需要一个中间变量C
a = 10
b = 20
c = a # a = 10 b = 20 c = 10
a = b # a = 20 b = 20 c = 10
b = c # a = 20 b = 10 c = 10
# 方法二:通过加减实现交换两个变量的值
a = 10
b = 20
a = a + b # a = 30 b = 20
b = a - b # a = 30 b = 10
a = a - b # a = 20 b = 10
# 方法三:直接同时交换两个变量
a = 10
b = 20
a,b = b,a # 直接同时交换
常见的数据类型
常见的数据又那些?
- int、float、str、bool、NoneType
如何查看数据的实际类型? - type(要查看的类型的数据)
- isinstance(数据,类型)
# type(要查看类型的数据) --> 返回数据的类型
print(type(10)) # int
print(type(3.14)) # float
print(type(True)) # bool
print(type(False)) # bool
print(type(None)) # NoneType
# isinstance(数据,类型) --> 返回布尔值True 或 False
num = -100
print(isinstance(num,int)) # True
print(isinstance(num,float)) # False
print(isinstance(num,bool)) # False
字符串
字符串的三种定义方式
# 双引号定义
s1 = "hello"
# 单引号定义
s2 = 'hello'
# 三引号定义(多行字符串)
s3 = """
尊敬的客户:
感谢您选择我们的产品.
我们将会为您竭诚服务.
祝好~
"""
转义字符
常见的转义字符
| 转义字符 | 作用 |
|---|---|
\n | 光标切换到下一行开头 |
\t | 实现对齐缩进一个制表位 |
\\ | 输出一个反斜杠 \ |
\' | 输出单引号 ' |
\" | 输出双引号 " |
\r | 回车,光标回到本行开头 |
\b | 退格,删除前一个字符 |
\0 | 空字符,字符串结束标记 |
字符串拼接
字符串拼接是把多个字符串合并为一个新字符串,原有字符串不会被修改。
# 多个字符串字面量直接写
slogan = "黑马程序员" "成就IT黑马"
print(slogan) # 输出黑马程序员成就IT黑马
# 使用 + 拼接字符串
s1 = "人生苦短"
s2 = "我用python"
res = s1 + s2
print(res) # 人生苦短我用python
# 使用 += 累加拼接
s = "宝剑锋从磨砺出"
s += "梅花香自苦寒来"
print (s) # 宝剑锋从磨砺出梅花香自苦寒来
# 使用.join()拼接字符串
s1 = "天行健"
s2 = "君子以自强不息"
list_str = [s1, s2]
res = "".join (list_str)
print (res) # 天行健君子以自强不息
# 案例:根据一下字面量输出 大家好,我是涛哥,今年18岁,学习的专业是软件工程,爱好是Python、Java
name = "涛哥"
age = 18
project = "软件工程"
hobby = "Python、Java"
print("大家好,我是" + name + ",今年" + str(age) + "岁,学习的专业是" + project + ",爱好是" + hobby)
思考:为什么age前面要加一个str()
- 因为+号字符串拼接只能是字符串与字符串之间拼接,不能将字符串与非字符串拼接,age是整数类型需要转成字符串进行拼接.
字符串格式化
字符串格式化是按照预设模板,把变量、数值、表达式填充到字符串指定位置,实现拼接、排版、对齐、小数保留、进制转换.
# % 格式化
s1 = "天生我材必有用"
s2 = "千金散尽还复来"
res = "%s%s" % (s1, s2)
print(res) # 天生我材必有用千金散尽还复来
# .format() 格式化
s1 = "业精于勤"
s2 = "荒于嬉"
res = "{}{}".format(s1, s2)
print(res) # 业精于勤荒于嬉
# f-string 格式化(推荐使用此方法)
s1 = "莫等闲"
s2 = "白了少年头"
res = f"{s1}{s2}"
print(res) # 莫等闲白了少年头
# .Template 模板格式化(专门用于安全场景,网页渲染、外部不可信文本拼接,防止注入)
from string import Template
tpl = Template("$s1,$s2")
res = tpl.substitute(s1="锲而不舍",s2="金石可镂")
print(res) # 锲而不舍,金石可镂
输入与输出
input语句的功能是获取键盘输入的数据,具体用法是s = input(提示信息)
print语句的功能是将数据输出到控制台,具体用法是print(输出的数据)
name = input('您的姓名:') # 输入星码长栖
age = input('您的年龄:') # 输入18
print(f'您的姓名:{name},年龄:{age}') # 输出您的姓名:星码长栖,年龄:18
# 案例:小智的银行卡中有10000元,现在到ATM进行取钱操作,完毕后展示其银行卡余额
total = 10000 # 银行卡总余额
password = input('请输入密码:') # 输入123123
print(f'密码正确,密码为{password}') # 输出密码正确,密码为123123
num = int(input('请输入取款金额:')) # 输入1000
total -= num # 计算银行卡余额
print(f'取款成功,取款{num}元,剩余{total}元') # 输出取款成功,取款1000元,剩余9000元
为什么num后面input要加int()?
- 因为input输入的是字符串,进行数值运算的时候需要转成整数类型.
运算符
算术运算符
算术运算符是用于执行基本的数学运算的符号,作用于一个或多个操作数上,并产生一个计算结果。
| 运算符 | 描述 | 举例说明 |
|---|---|---|
+ | 加法 | 1 + 5 = 6 |
- | 减法 | 8 - 3 = 5 |
* | 乘法 | 3 * 8 = 24 |
/ | 除法 | 10 / 5 = 2(算出来的是小数) |
// | 整除 | 10 // 3 = 3(只保留整数) |
% | 取余 | 10 % 3 = 1 |
** | 幂指数 | 10 ** 3 = 1000 |
算术运算符的优先级:括号 > 幂指数 > 乘、除、整除、取余 > 加、减
# 案例:输入两个数x和y,计算和x-y
x = input('输入x的值:') # 输入x的值:0.5
y = input('输入y的值:') # 输入y的值:0.4
print(int(x)-int(y)) # 输出0.1
print(float(x)-float(y)) # 输出0.09999999999999998
为什么浮点数运算输出的是0.09999999999999998?
- 浮点数的底层运算逻辑是进行二进制的存储和运算,而二进制无法准确的表示所有小数,因此所有浮点数运算都可能存在精度丢失问题.
赋值运算符
| 运算符 | 描述 | 举例说明 |
|---|---|---|
= | 简单赋值,将右侧值赋给左侧变量 | a = 5,变量 a 的值为 5 |
+= | 加法赋值,等价于 a = a + 数值 | a = 2;a += 3,等价a = a + 3,结果 a = 5 |
-= | 减法赋值,等价于 a = a - 数值 | a = 8;a -= 3,等价a = a - 3,结果 a = 5 |
*= | 乘法赋值,等价于 a = a * 数值 | a = 3;a *= 4,等价a = a * 4,结果 a = 12 |
/= | 除法赋值,等价于 a = a / 数值,结果为浮点数 | a = 10;a /= 2,等价a = a / 2,结果 a = 5.0 |
//= | 整数整除赋值,等价于 a = a // 数值 | a = 10;a //= 3,等价a = a // 3,结果 a = 3 |
%= | 取余赋值,等价于 a = a % 数值 | a = 10;a %= 3,等价a = a % 3,结果 a = 1 |
**= | 幂运算赋值,等价于a = a ** 数值 | a = 10;a **= 3,等价a = a ** 3,结果 a = 1000 |
比较运算符
比较运算符,也称为关系运算符,用于比较两个值之间的关系。会计算运算符两边的表达式,然后返回一个布尔值作为结果(True表示比较关系成立;False表示比较关系不成立)。一般用于循环判断或者if条件判断。
| 运算符 | 名称 | 作用描述 | 示例 | 结果 |
|---|---|---|---|---|
== | 等于 | 判断左右两边值是否相等 | 5 == 53 == 6 | True False |
!= | 不等于 | 判断两边值不相等 | 5 != 32 != 2 | True False |
> | 大于 | 左边 > 右边则成立 | 9 > 42 > 7 | True False |
< | 小于 | 左边 < 右边则成立 | 1 < 86 < 1 | True False |
>= | 大于等于 | 左边大于 或 等于右边 | 5 >= 53 >= 7 | True False |
<= | 小于等于 | 左边小于 或 等于右边 | 4 <= 98 <= 2 | True False |
逻辑运算符
逻辑运算符是用于连接多个条件(布尔)表达式(其值为“真”或“假”),并返回一个最终布尔结果的运算符。
| 运算符 | 描述 | 实例 |
|---|---|---|
| and | 逻辑与 | 多个条件同时成立为True,否则为False |
| or | 逻辑或 | 所有条件全都不成立则为False,否则只要有一个成立则为True |
| not | 逻辑非 | 取反操作,True变为False,False变为True |
if 条件判断
if条件判断是只有满足指定条件,才会执行对应代码逻辑。
# if 条件判断的基本格式
if 要判断的条件1:
条件1成立时,要执行对应的操作
elif 要判断的条件2:
条件2成立时,要执行对应的操作
else:
条件1和条件2都不成立时,要执行对应的操作
# 案例1:如果分数超过680,我要去清华读书
score = 700
if score > 680:
print("欢迎来到清华读书")
print("也恭喜你即将踏入精彩的大学生活")
# 案例2:结合前面学习的输入输出及if条件判断的知识,完成B站登录功能的实现(正确账号和密码为18888888888/666888)
username = input("请输入账号:")
password = input("请输入密码:")
if username == "18888888888" and password == "666888":
print("登录成功")
else:
print("账号或密码错误")
# 案例3:输入一个年份判断是平年还是闰年
# 判断闰年方法:
# 1.非整百年份,且能被4整除的年份是闰年
# 2.整百年份(如1900、2000)必须被400整除才是闰年
year = int(input("请输入年份:"))
if (year % 100 != 0 and year % 4 == 0) or year % 400 == 0:
print(f"{year}是闰年!")
else:
print(f"{year}不是闰年!")
match 模式匹配
match 模式匹配是 Python3.10 及以上版本新增的多分支判断语法,用来优化冗长的if-elif-else结构,专门做结构、值的匹配,逻辑分层更加清晰直观,case _等同于 if 结构里的 else 兜底分支。
# match模式匹配的基本格式
match 待匹配对象:
case 匹配条件1:
匹配1命中后执行代码
case 匹配条件2:
匹配2命中后执行代码
case _:
前面所有条件都不匹配时执行(兜底分支)
# 案例:基于match...case实现一个简易的计算器,可以实现+ - * / 运算,用户输入需要运算的两个数以及运算符之后,就可以进行计算。
num1 = float(input("请输入第一个数:"))
oper = input("请输入运算符:")
num2 = float(input("请输入第二个数:"))
match oper:
case "+":
print(f"{num1} {oper} {num2} = {num1 + num2}")
case "-":
print(f"{num1} {oper} {num2} = {num1 - num2}")
case "*":
print(f"{num1} {oper} {num2} = {num1 * num2}")
case "/" if num2 != 0: # if条件成立才执行这个case
print(f"{num1} {oper} {num2} = {num1 / num2}")
case _:
print("操作不支持!")
循环
循环语句可以让一段代码重复执行,Python 主要分为 while 循环、for 循环,用来简化重复代码,不用反复复制粘贴。
while循环
# while 循环基础格式
while 条件表达式:
循环体语句1
循环体语句2
else: # 当上面条件表达式不成立时退出循环执行else
循环结束执行的语句
# 案例:计算1-100之间所有偶数之和。
i = 1
sum = 0
while i <= 100:
if i % 2 == 0:
sum += i
i+=1
print(f"1一100之间所有偶数的累加之和是{sum}")
for循环
# for循环基础格式
for 元素 in 待处理数据集:
循环体代码
else:
循环结束时,执行的代码
# 案例1:遍历输出输入的字符串
msg = input("请输入字符串:")
for s in msg:
print(s)
else:
print("遍历结束!")
# 案例2:计算100-500之间所有3的倍数的数字之和。
sum = 0
for i in range(100,501):
if i % 3 == 0:
sum += i
i += 1
print(f"100-500之间所有3的倍数的数字之和是{sum}")
嵌套循环
嵌套循环:在一个循环内部,再定义另一个循环,外层循环执行 1 次,内层循环会完整跑完一整轮。嵌套循环分为:while 嵌套 while、for 嵌套 for、while 与 for 互相嵌套,最常用for 嵌套 for。
# 案例1:输出99乘法表
for i in range(1,10): # 外循环控制行
for j in range(1,i+1): #内循环控制列
print(f"{j} * {i} = {i * j}",end = "\t") # end = "\t"表示不换行,末尾加一个制表符
print()
# 案例2:根据输入的用户名密码执行登录操作,具体要求如下:
# 1.正确的用户名和密码为admin/666888、zhangsan/123456、taoge/888666
# 2.输入用户名和密码进行登录,直到登录成功,程序结束运行;如果登录失败,则继续输入用户名和密码进行登录
# 3.输入的用户名和密码不能为空!
# 4.登录成功:输出"登录成功,进入B站首页~"
# 5.登录失败:输出"用户名或密码错误,请重新输入!"
while True:
username = input("请输入用户名:")
password = input("请输入密码:")
if username == "" or password == "":
print("用户名或密码不为空!请重新输入")
continue # continue的作用是跳出本次循环
if username == "admin" and password == "666888":
print("登录成功,进入B站首页~")
break # break的作用是跳出本层循环
elif username == "zhangsan" and password == "123456":
print("登录成功,进入B站首页~")
break
elif username == "taoge" and password == "888666":
print("登录成功,进入B站首页~")
break
else:
print("用户名或密码错误,请重新输入!")
# 案例3:猜数字游戏
# 系统生成随机数让用户猜
# 如果猜错,系统提示猜大了还是猜小了,然后继续猜数字
# 如果猜对了,系统给出提示结束游戏
import random # 导入random模块
number_random = random.randint(1,100) # 生成随机数
while True: # 循环输入判断
number = int(input("请输入一个数:"))
if number_random == number:
print("猜对了!")
break
elif number > number_random:
print("猜大了!")
else:
print("猜小了!")
数据容器
一种可以容纳多份数据的数据类型(容器),容纳的每一份数据称之为1个元素,每一个元素都可以是任意类型的数据,如:字符串、数字、布尔等。
列表list
列表是数据容器中的一类,是一次性可以存储多个数据(元素)的。
列表的特点:可以存储不同类型的元素、元素有序、可以重复、元素可以修改。
# 列表list的格式
列表名称 = [元素1,元素2,元素3...]
# 列表操作
# 定义列表
s = [56,23,43,12,"A","hello",True,None]
# 读取
print(s[0]) # 正向索引从0开始
print(s[-1]) # 反向索引从-1开始
# 修改
s[4] = "ABC"
print(s)
# 删除
del s[1]
print(s)
# 遍历
for i in s:
print(i)
# 切片操作 s[开始索引:结束索引:步长]
print(s[0:5:1]) # [56, 43, 12, 'ABC', 'hello']
print(s[:5:1]) # [56, 43, 12, 'ABC', 'hello']
print(s[:5:]) # [56, 43, 12, 'ABC', 'hello']
print(s[:5]) # [56, 43, 12, 'ABC', 'hello']
print(s[0:5:2]) # [56, 12, 'hello']
print(s[0:-2:1]) # [56, 43, 12, 'ABC', 'hello']
列表常见的方法
| 方法 | 作用 | 样例 |
|---|---|---|
| append() | 在列表的尾部追加元素 | s.append(10086) |
| insert() | 在指定索引之前,插入该元素 | s.insert(0,92) |
| remove() | 移除列表中第一个匹配到的值 | s.remove(75) |
| pop() | 删除列表中指定索引位置的元素(如果未指定索引,默认删除最后一个) | s.pop(2) s.pop() |
| sort() | 对列表进行排序(列表元素的数据类型一致,才可以进行排序) | s.sort() |
| reverse() | 反转列表元素 | s.reverse() |
# 案例:将用户输入的10个数字,存储到一个列表中,并将列表中的数字进行排序,输出其中的最小值、最大值和平均值。
list = []
for i in range(10):
list.append(int(input(f"请输入第{i+1}个数字:")))
list.sort()
print(f"输入的10个输中最小的是{list[0]},最大的是{list[9]},平均值是{sum(list)/10}")
字符串str
字符串是字符的容器,一个字符串中可以存放任意数量的字符。如:”Python”、’Python’、”””Python”””。
字符串的特点:不可变性(无法修改)、有序性、可迭代性。
# 字符串 基本操作
s = "hello-python"
print(s[4]) # 正向索引 输出0
print(s[-4]) # 反向索引 输出t
# 遍历输出每一个元素
for i in s:
print(i)
# 切片
print(s[0:5:1]) # 截取前5个字符hello
字符串常见的方法
| 方法 | 作用 | 样例 |
|---|---|---|
| upper() | 将字符串全部转为大写 | s.upper() |
| lower() | 将字符串全部转为小写 | s.lower() |
| strip() | 去除字符串首尾空白 (空格、换行、tab) | s.strip() |
| split() | 按照分隔符分割字符串 | s.split(“,”) s.split() |
| join() | 使用字符拼接序列,返回新字符串 | “-“.join(list1) |
| replace() | 替换字符串中的指定子串 | s.replace (“旧”,”新”) |
| find() | 查找子串,找到返回下标,找不到返回‑1 | s.find(“abc”) |
| count() | 统计子字符串出现的次数 | s.count(“a”) |
| startswith() | 判断字符串是否以指定内容开头 | s.startswith(“hello”) |
| endswith() | 判断字符串是否以指定内容结尾 | s.endswith(“.txt”) |
| isdigit() | 判断字符串是否全部由数字构成 | s.isdigit() |
# 案例:邮箱格式验证,用户输入一个邮箱,验证邮箱格式是否正确(包含一个@和至少一个.),如果输入正确,输出"邮箱格式正确",否则输出"邮箱格式错误”。
# 注意:本案例只是用来学习字符串,正式开发时使用正则表达式!
mail = input("请输入邮箱:")
if mail.count("@") == 1 and mail.count(".") >= 1:
print("邮箱格式正确")
else:
print("邮箱格式错误")
元组tuple
元组是不可变的序列,类似于列表,但创建后不能修改。
元组的特点:可以存储不同类型的元素、元素有序、可以重复,但创建后不能修改(支持索引访问、切片)。
# 定义元组
元组名称 = (元素1、元素2、元素3……)
# 定义空元组
元组名称 = ()
元组名称 = tuple()
元组常见的方法
# 元组的基本操作
# 定义
t1 = (23, 31, 53, 35, 24, 54, 43, 23)
print(t1)
print(type(t1))
# 索引访问
print(t1[0])
print(t1[-1])
# 切片
print(t1[0:5:1])
# count统计个数
print(t1.count(23))
# index获取元素第一次出现的索引位置
print(t1.index(53))
# 组包与解包
# 组包:将多个值合并到一个容器(元组、列表)中。
# 解包:将容器(元组、列表)解开成独立的元素,分别赋值给多个变量。
t1 = 5, 7, 9, 1
a, b, c, d = t1 # a = 5, b = 7, c = 9, d = 1
#(*)扩展解包
x, *y, z = t1 # x = 5, y = [7, 9], z = 1
s, *o = t1 # s = 5, o = [7,9,1]
*o, e = t1 # o = [5, 7, 9], e = 1
"""
案例:根据如下提供的学生成绩单,完成如下需求:
1.计算每个学生的总分、各科平均分,然后一并输出出来。
2.统计各科成绩的最低分、最高分、平均分,并输出。
3.查找成绩优秀(平均分大于90)的学生,并输出。
"""
students = (
("S001", "王林", 85, 92, 78),
("S002", "李慕婉", 92, 88, 95),
("S003", "十三", 78, 85, 82),
("S004", "曾牛", 88, 79, 91),
("S005", "周轶", 95, 96, 89),
("S006", "王卓", 76, 82, 77),
("S007", "红蝶", 89, 91, 94),
("S008", "徐立国", 75, 69, 82),
("S009", "许木", 86, 89, 98),
("S010", "遁天", 66, 59, 72)
)
print("学号\t姓名\t语文\t数学\t英语\t总分\t平均分")
# 计算每个学生的总分、各科平均分,然后一并输出出来。
for s in students:
id, name, chinese, math, english = s
total = chinese + math + english
avg = total / 3
print(f"{id}\t{name}\t{chinese}\t{math}\t{english}\t{total}\t{avg:.1f}")
print()
# 统计各科成绩的最低分、最高分、平均分,并输出。
chinese_scores = [s[2] for s in students]
math_scores = [s[3] for s in students]
english_scores = [s[4] for s in students]
print(f"语文最低分:{min(chinese_scores)},最高分:{max(chinese_scores)},{sum(chinese_scores)/len(chinese_scores)}")
print(f"数学最低分:{min(math_scores)},最高分:{max(math_scores)},{sum(math_scores)/len(math_scores)}")
print(f"英语最低分:{min(english_scores)},最高分:{max(english_scores)},{sum(english_scores)/len(english_scores)}")
print()
# 查找成绩优秀(平均分大于90)的学生,并输出。
print("优秀学生(平均分>90)名单:")
for s in students:
id, name, chinese, math, english = s
avg = (chinese + math + english) / 3
if avg > 90:
print(f"学号:{id},姓名:{name},平均分:{avg:.1f}")
集合set
集合是一种无序的、不可重复、可修改的数据容器。
# 定义集合
s1 = {"C", "D", "X", "T", "O", "u"}
# 定义空集合
s2 = set()
# 定义
s1 = {5, 3, 2, 0, 9, 12, 43, 64, 22, 5, 0}
print(s1) # 输出{0, 64, 2, 3, 5, 9, 43, 12, 22}自动去重且无序
集合常见的方法
| 方法 | 作用 | 样例 |
|---|---|---|
| add() | 向集合添加单个元素 | s.add(10) |
| update() | 批量添加多个元素,可传入列表 / 元组 / 集合 | s.update([20,30]) |
| remove() | 删除指定元素,元素不存在会报错 | s.remove(10) |
| discard() | 删除指定元素,元素不存在不报错 | s.discard(10) |
| pop() | 随机删除并返回一个元素 | val = s.pop() |
| clear() | 清空集合所有元素 | s.clear() |
| copy() | 复制集合,返回新集合 | s2 = s.copy() |
| difference() | 求两个集合的差集(包含在第一个集合但不在第二个集合的元素) | s1.difference(s2) |
| union() | 求两个集合的并集 | s1.union(s2) |
| intersection() | 求两个集合的交集 | s1.intersection(s2) |
| 运算 | 作用 | 样例 |
|---|---|---|
| & | 交集,取两边都有的元素 | s1 & s2 |
| | | 并集,合并去重所有元素 | s1 | s2 |
| – | 差集,在 s1 不在 s2 的元素 | s1 – s2 |
| ^ | 对称差集,两边互不共有的元素 | s1 ^ s2 |
"""
案例:根据提供的班级学生的选课情况,完成如下需求:
1.找出同时选修了法语和艺术的学生
2.找出同时选修了所有四门课程的学生
3.找出选修了足球,但是没有选修篮球的学生
4.统计每一个学生选修的课程数量
"""
#选修足球学生名单
football_set={"王林", "曾牛", "徐立国","遁天","天运子","韩立", "厉飞雨","乌丑","紫灵"}
#选修篮球学生名单
basketball_set={"张铁", "墨居仁","王林", "姜老道", "曾牛", "王蝉", "韩立", "天运子", "李化元","厉飞雨", "云露"}
#选修法语学生名单
french_set={"许木", "王卓", "十三","虎咆", "姜老道", "天运子","红蝶", "厉飞雨", "韩立", "曾牛"}
#选修艺术学生名单
art_set={"遁天","天运子","韩立", "虎咆", "姜老道","紫灵"}
# 1.找出同时选修了法语和艺术的学生
fa_set = french_set.intersection(art_set)
print(f"同时选修了法语和艺术的学生名单:{fa_set}")
# 2.找出同时选修了所有四门课程的学生
all_set = football_set & basketball_set & french_set & art_set
print(f"同时选修了所有课程的学生名单:{all_set}")
# 3.找出选修了足球,但是没有选修篮球的学生
f_set = football_set.difference(basketball_set)
print(f"选修了足球,但是没有选修篮球的学生名单:{f_set}")
# 4.统计每一个学生选修的课程数量
students_set = football_set.union(basketball_set).union(french_set).union(art_set)
students_list = [*football_set, *basketball_set, *french_set, *art_set]
for s in students_set:
print(f"{s} 选修了{students_list.count(s)}门课程。")
字典dict
字典里面存储的是 键值对(key:value) 类型的数据,可以根据 键(key) 找到对应的 值(value) 。
# 字典
# 定义字典
dict1 = {"王林":670, "李慕婉":608, "徐立国":580, "韩立":688, "王林":800}
print(dict1) # 输出{'王林': 800, '李慕婉': 608, '徐立国': 580, '韩立': 688}key不可重复,如有重复,后面的值会覆盖前面的值
# key必须是不可变类型(str, int, float, tuple), 不能是 list、set、dict
dict2 = {0:670, 1.5:608, (1,2):580}
print(dict2)
# 访问字典
print(dict1["王林"]) # 800
dict1["王林"] = 666
print(dict1["王林"]) # 666
字典常见的方法
| 方法 | 作用 | 样例 |
|---|---|---|
| get() | 根据 key 获取 value,key 不存在返回 None,不会报错 | d.get(“name”) |
| keys() | 获取字典中所有的键 | d.keys() |
| values() | 获取字典中所有的值 | d.values() |
| items() | 获取字典所有键值对,返回 (key,value) 序列 | d.items() |
| update() | 批量更新 / 添加键值对 | d.update({“age”:18}) |
| pop() | 根据 key 删除键值对,并返回对应 value | d.pop(“name”) |
| popitem() | 删除字典最后一组键值对,返回该键值对 | k,v = d.popitem() |
| clear() | 清空字典内所有元素 | d.clear() |
| copy() | 浅拷贝字典,生成新字典 | d2 = d.copy() |
| setdefault() | 获取 key 对应值;key 不存在则新增 key,设置默认值 | d.setdefault (“gender”,”男”) |
"""
案例:开发一个购物车管理系统,实现商品信息的添加、修改、删除、查询功能。系统使用字典结构存储商品数据,通过控制台菜单与用户交互。具体功能如下:
1.添加购物车:用户根据提示录入商品名称、以及该商品的价格、数量,保存该商品信息到购物车。
2.修改购物车:要求用户输入要修改的购物车商品名称,然后再提示输入该商品的价格、数量,输入完成后修改该商品信息。
3.删除购物车:要求用户输入要删除的购物车名称,根据名称删除购物车中的商品。
4.查询购物车:将购物车中的商品信息展示出来,格式为:"商品名称:XXX,商品价格:XXX,商品数量:XXX"。
5.退出购物车。
"""
shopping_cart = {}
# 制作菜单
menu = """
######## 购物车系统 ########
# 1.添加购物车 #
# 2.修改购物车 #
# 3.删除购物车 #
# 4.查询购物车 #
# 5.退出购物车 #
###########################
"""
print("欢迎使用购物车管理系统")
while True:
# 打印菜单
print(menu)
# 执行具体的操作
choice = input("请选择要执行的操作(1-5):")
match choice:
case "1": # 添加购物车
goods_name = input("请输入商品的名称:")
goods_price = float(input("请输入商品的价格:"))
goods_num = int(input("请输入商品的数量:"))
if goods_name in shopping_cart:
print("该商品已存在,请重新选择")
else:
shopping_cart[goods_name] = {"price": goods_price, "num": goods_num}
print("商品添加成功")
case "2": # 修改购物车
goods_name = input("请输入商品的名称:")
if goods_name not in shopping_cart:
print("该商品不存在,请重新选择")
else:
goods_price = float(input("请输入商品最新的价格:"))
goods_num = int(input("请输入商品最新的数量:"))
shopping_cart[goods_name] = {"price": goods_price, "num": goods_num}
print("商品修改成功")
case "3": # 删除购物车
goods_name = input("请输入要删除的商品名称:")
if goods_name not in shopping_cart:
print("该商品不存在,请重新选择")
else:
del shopping_cart[goods_name]
print("商品删除成功")
case "4": # 查询购物车
for good_name in shopping_cart.keys():
good_info = shopping_cart[good_name]
print(f"商品名称:{good_name},商品价格:{good_info['price']},商品数量:{good_info['num']}")
case "5": # 退出购物车
break
case _: # 匹配其他所有情况
print("非法操作,不支持!")
总结
| 特性 | 字符串(str) | 列表(list) | 元组(tuple) | 集合(set) | 字典(dict) |
|---|---|---|---|---|---|
| 有序性 | 有序 | 有序 | 有序 | 无序 | 有序 (3.7+) |
| 重复元素 | 允许 | 允许 | 允许 | 不允许 | key 不允许 |
| 可变性 | 不可变 | 可变 | 不可变 | 可变 | 可变 |
| 索引访问 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
| 切片操作 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
| 使用场景 | 文本处理 | 有序可重复数据集合 | 固定数据记录 | 去重数据集合 | 键值对 |
函数
函数基础
函数是组织好的、可重复使用的、用来实现特定功能的代码片段。
函数的注意事项:
- 函数必须先定义,后调用
- 函数定义时并不会执行,只有调用函数时才会执行。
- 函数通过缩进来描述归属关系
# 定义函数
def 函数名(参数列表):
函数体
return 返回值
# 调用函数
函数名(参数值)
# 定义函数
def out_line():
print("-------------")
# 调用函数
out_line()
在定义函数时,根据业务需要,可以指定参数和返回值,例如:
# 计算阶乘
def factorial(i):
fac = 1
for n in range(2,i+1):
fac *= n
return fac
print(factorial(5)) # 120
# 计算两数区间之和
def intervals_sum(a,b):
if a > b:
a, b = b, a
sum = 0
for i in range(a,b+1):
sum += i
return sum
print(intervals_sum(3,9)) # 42
函数的说明文档(Docstring)是写在函数开头,用三个引号包裹的字符串,用于解释函数的功能、参数、返回值等信息,方便调用者清楚函数的具体作用及细节。
# 计算阶乘
def factorial(i):
"""
该函数计算输入的i的阶乘
:param i: 输入一个正整数i
:return: 正整数i的阶乘
"""
fac = 1
for n in range(2,i+1):
fac *= n
return fac
print(factorial(5))
help(factorial)
嵌套调用指的是在一个函数中,又调用了另外一个函数。
函数调用遵循栈结构,最后被调用的函数最先返回LIFO(Last In First Out,后进先出)
# 输出结果:
# a ... before
# b ... before
# c ...
# b ... after
# a ... after
def function_a():
print("a ... before")
function_b()
print("a ... after")
def function_b():
print("b ... before")
function_c()
print("b ... after")
def function_c():
print("c ...")
function_a()
函数的案例:
# 计算阶乘
def factorial(i):
"""
该函数计算输入的i的阶乘
:param i: 输入一个正整数i
:return: 正整数i的阶乘
"""
fac = 1
for n in range(2,i+1):
fac *= n
return fac
print(factorial(5))
help(factorial)
# 计算两数区间之和
def intervals_sum(a,b):
if a > b:
a, b = b, a
sum = 0
for i in range(a,b+1):
sum += i
return sum
print(intervals_sum(3,9)) # 42
def function_a():
print("a ... before")
function_b()
print("a ... after")
def function_b():
print("b ... before")
function_c()
print("b ... after")
def function_c():
print("c ...")
function_a()
# 输出结果:
# a ... before
# b ... before
# c ...
# b ... after
# a ... after
#案例1:定义一个函数:根据传入的底和高计算三角形面积的函数(三角形面积=底*高/2)。
def triangle_area(b,h):
"""
根据传入的底和高计算三角形面积
:param b: 三角形的底
:param h: 三角形的高
:return: 返回三角形的面积
"""
s = b * h / 2
return s
print(f"底为20,高为30的三角形面积为{triangle_area(20,30)}")
#案例2:定文一个函数:计算传入的字符串中元音字母的个数(元音字母为aeiouAEIou)。
def count_aeiou(str):
"""
计算传入的字符串中元音字母的个数(元音字母为aeiouAEIOU)
:param str: 输入一个字符串
:return: 字符串中元音字母的个数
"""
aeiou = "aeiouAEIOU"
aeiou_count = 0
for s in str:
if s in aeiou:
aeiou_count += 1
return aeiou_count
print(f"Hello world!共有{count_aeiou('Hello world!')}个元音字母")
#案例3:定义一个函数:计算传入的班级学员高考成绩列表中成绩的最高分、最低分、平均分(保留1位小数),并返回。
def scores_result(scores):
"""
计算传入的成绩列表中的最高分、最低分、平均分(保留1位小数)
:param scores: 包含学员成绩的列表,例如 [23,56,77,87,99,98]
:return: 元组 (最高分, 最低分, 平均分),平均分保留1位小数
"""
s_max = max(scores)
s_min = min(scores)
s_avg = round(sum(scores) / len(scores), 1)
return s_max, s_min, s_avg
s_max, s_min, s_avg = scores_result([23,56,77,87,99,98])
print(f"最高分:{s_max},最低分:{s_min},平均分:{s_avg}")
函数进阶
变量的作用域指的是变量的作用范围(标识这个变量在哪里可以使用,在哪儿不可以使用)。
全局变量: 在函数之外定义的变量,称之为全局变量,在整个文件中(包括函数内)都可以使用(通常定义在文件的顶部)。
局部变量: 在函数内部定义的变量,称之为局部变量,只能在该函数内部使用,外部无法访问(函数执行完毕后,会自动销毁其内部局部变量)。
# 定义全局变量
num1 = 199
num2 = 299
num3 = 399
# 定义函数circle_area
def circle_area(r):
pi = 3.14
area = pi * r * r
print(num1) # 函数内部可以使用全局变量
return area
# 定义函数triangle_area
def triangle_area(b,h):
global num3
num2 = 999
num3 = 999
print(num2) # 999
print(num3) # 999
s = b * h / 2
return s
# 调用函数
# print(area) 函数外部使用局部变量报错未定义
c_area = circle_area(10)
print(c_area)
print(num1)
print(num2) # 299,在函数内部不能直接修改全局变量
print(num3) # 999,只有使用global声明了在函数内使用全局变量才能修改全局变量的值
传参方式指的是,在调用函数时,传递实参的方式。
- 位置参数: 调用函数时根据函数定义时的位置来传递参数。
- 关键字参数: 调用函数时以 函数定义时形参名称 作为关键字,以 “键 = 值” 的形式来传递参数(不要求顺序)。
# 位置参数
# 定义函数,形参顺序:name, age
def show_info(name, age):
print(f"姓名:{name},年龄:{age}")
# 位置参数:按定义顺序传值,第一个实参给name,第二个给age
show_info("小明", 18)
# 输出:姓名:小明,年龄:18
# 位置写反,结果就出错
show_info(18, "小明")
# 输出:姓名:18,年龄:小明
# 关键字参数
def show_info(name, age):
print(f"姓名:{name},年龄:{age}")
# 关键字参数,顺序可以颠倒
show_info(age=20, name="小红")
# 输出:姓名:小红,年龄:20
# 位置参数 + 关键字参数混用:位置参数必须写在前面
show_info("小李", age=22)
# show_info(name="小李",22) # 报错!关键字参数后面不能跟位置参数
默认参数也称为缺省参数,用于在定义函数时,为参数提供默认值,调用函数时,可以不传递有默认值的参数。
默认参数的注意事项:
- 默认参数必须放在没有默认值的参数列表的后面,一个函数在定义时是可以设置多个默认参数的。
- 函数调用时,如果为默认参数传递了值,则会修改默认的参数值;如果没有传递该参数,则直接使用默认值。
# height设置默认参数170,必须放在age后面(无默认参数在前)
def show_info(name, age, height=170):
print(f"姓名:{name},年龄:{age},身高:{height}")
# 不传递默认参数height,使用默认值170
show_info("小张", 19)
# 输出:姓名:小张,年龄:19,身高:170
# 给默认参数传新值,覆盖默认
show_info("小王", 21, height=178)
# 输出:姓名:小王,年龄:21,身高:178
不定长参数也叫可变参数,用于函数定义及调用时参数个数不确定(0个或多个)的场景。
*args:接收位置不定长参数,打包成元组 tuple- `kwargs`:接收关键字不定长参数,打包成字典 dict**
# *args 接收任意多个位置参数
def sum_all(*args):
print("args元组:", args)
total = 0
for num in args:
total += num
return total
print(sum_all()) # 不传参 () → 0
print(sum_all(1,2,3)) # 传3个参数 (1,2,3) →6
print(sum_all(10,20,30,40)) # 传4个参数 →100
# **kwargs接收任意多个关键字参数
def print_dict(**kwargs):
print("kwargs字典:", kwargs)
print_dict()
print_dict(name="阿泽", age=20, city="武汉")
# kwargs字典: {'name': '阿泽', 'age': 20, 'city': '武汉'}
函数的参数类型:
- 普通参数:数字、布尔、字符串、列表、元组、集合、字典等。
- 特殊参数:函数。
# 加
def add (x, y):
return x+y
# 减
def subtract (x, y):
return x-y
# 乘
def multiply (x, y):
return x*y
# 除
def divide (x, y):
return x/y
# 计算
def calc(x, y, oper):
return oper(x, y)
# 调用函数
print(calc(10, 2, add)) # 12
print(calc(10, 2, subtract)) # 8
print(calc(10, 2, multiply)) # 20
print(calc(10, 2, divide)) # 5.0
匿名函数指的是没有名称的函数,需要通过lambda表达式来声明函数,可以简化简单函数的编写(单行表达式)。
注意:
- lambda 没有 return,表达式的结果自动作为返回值
- 只能写一行表达式,不能写复杂代码、循环、if 语句块(三元表达式除外)
- 匿名函数本身没有名字,一般赋值给变量,或者直接作为参数传给其他函数
# 普通函数写法
def add(x, y):
return x + y
# lambda匿名函数写法
add_lambda = lambda x, y: x + y
# 调用
print(add_lambda(3, 5)) # 输出 8
类型注解
类型注解是Python中的一种语法特性,用于明确标识变量、函数参数和返回值的数据类型,从而使代码更清晰、更安全、更易维护。
类型注解只是提示,运行时不会强制校验,执行时不会报错。
# 显式类型注解
name: str = "小明"
age: int = 18
score: float = 95.5
is_ok: bool = True
name = 123 # 提示应为str,实际为int
类型推断是指Python解释器自动推断出变量、表达式或函数返回值的数据类型的能力,而无需开发者显式声明。
# 类型推断:没有写注解,Python自动推断类型
city = "武汉" # 推断为 str
height = 175 # 推断为 int
为函数添加类型注解,其实主要就是为函数的参数和返回值添加类型注解,具体语法如下:
# 函数类型注解
def circle_area_len(r: int) -> float:
return round(3.14 * r * r, 1), round(2 * 3.14 * r, 1)
al = circle_area_len(10)
print(al)
模块
Python模块(module): 一个.py文件就是一个模块,模块是Python程序的基本组织单位。在模块中可以定义变量、函数、类,以及可执行的代码。在使用模块中提供的功能之前,必须得先导入,再使用。
模块的特点:
- 提高代码的复用性
- 降低开发门槛
- 避免命名冲突
| 导入形式 | 代码样例 | 调用方式 | 调用方式 |
|---|---|---|---|
| import 模块名 | import random, os | 模块名.功能名 | random.randint(10, 100) |
| import 模块名 as 别名 | import random as rd | 别名.功能名 | rd.randint(10, 100) |
| from 模块名 import 功能名 | from random import randint, choice | 功能名 | randint(10, 100) |
| from 模块名 import 功能名 as 别名 | from random import randint as rint | 别名 | rint(10, 100) |
| from 模块名 import * | from random import * | 功能名 | randint(10, 100) |
# 导入模块
import random # 调用方式是模块名.功能名,例如random.randint
import random as rd # 给调用的random模块起了别名rd,使用rd.randint来执行
from random import randint # 只调用random模块中的randint
from random import * # 导入模块中的所有功能,调用时直接使用功能名,例如randint
for i in range(100):
print(rd.randint(1,100))
包: 本质就是一个文件夹,该文件夹中可以包含若干python模块,文件夹下还包含了一个 __init__.py 。
作用:模块文件较多时,用来管理多个模块。包的本质也是一个模块。
| 导入形式 | 代码样例 | 调用方式 | 调用示例 |
|---|---|---|---|
| import 包名.模块名 | import utils.my_fun | 包名.模块名.功能名 | utils.my_fun.log_separator1() |
| from 包名 import 模块名 | from utils import my_fun | 模块名.功能名 | my_fun.log_separator1() |
| from 包名 import * | from utils import * | 模块名.功能名 | my_fun.log_separator1() |
| from 包名.模块名 import 功能名 | from utils.my_fun import log_separator1 | 功能名 | log_separator1() |
| from 包名.模块名 import * | from utils.my_fun import * | 功能名 | log_separator1() |
面向对象
对象可以理解为现实中具体的人/物在程序中的数字化身(万物皆对象)。
它把一个人/物的特征(属性) 和 功能(方法) 打包到一起,是面向对象编程的 基本单元。
类:描述的是一组具有 相同属性(特征) 和 方法(功能/行为) 的模板。
对象:对象是 类的实例 ,是基于 类 创建出来的(实例对象)。
对象是由类创建出来的,创建对象的过程,也称为对象的实例化。一个类可以创建无数个对象。
# 定义类
# 类名命名规范遵循大驼峰命名法,每个单词首字母大写,中间没有分隔符
class 类名:
pass
# 创建对象
对象名 = 类名()
对象名.属性名1 = 属性值1
对象名.属性名2 = 属性值2
定义在类的外面的称之为函数,定义在类中的函数称之为方法。
# 定义类
class 类名:
def __init__(self, 参数列表):
self.属性名 = 参数值
self.属性名 = 参数值
# 创建对象
对象名 = 类名(参数列表)
对象名.方法名(实参)
# 定义类
class Car:
# __init__方法是初始化的方法,会在对象创建时自动调用,可以在该方法中为对象设置对应的属性
# self是第一个参数,表示当前所创建出来的实例对象
def __init__(self, c_color, c_brand, c_name, c_price):
self.color = c_color
self.brand = c_brand
self.name = c_name
self.price = c_price
print("Car 类型的对象初始化完毕,对象属性已经添加完毕。")
# 创建对象
c1 = Car("红色", "BMW", "X7", 8000000)
print(c1.__dict__)
c2 = Car("白色", "奔驰", "E300", 450000)
print(c2.__dict__)
在类中定义实例方法时,定义语法与之前学习的函数定义的方式是一致的。
# 定义类
class 类名:
def __init__(self, 参数列表):
self.属性名 = 参数值
self.属性名 = 参数值
def 方法名(self, 形参列表):
...
def 方法名(self, 形参列表):
...
# 创建对象
对象名 = 类名(参数列表)
# 定义类
class Car:
def __init__(self, c_color, c_brand, c_name, c_price):
self.color = c_color
self.brand = c_brand
self.name = c_name
self.price = c_price
print("Car 类型的对象初始化完毕,对象属性已经添加完毕。")
def running(self):
print(f"{self.brand} {self.name} 正在高速行驶中...")
def total_cost(self, discount, rate = 0.1):
"""计算提车的总费用"""
total_cost = self.price * discount + rate * self.price
return total_cost
# 创建对象
c1 = Car("红色", "BMW", "X7", 8000000)
# 调用对象中的方法
c1.running()
total1 = c1.total_cost(0.9, 0.2)
print("提车的总费用为:", total1)
total2 = c1.total_cost(0.9)
print("提车的总费用为:", total2)
魔法方法是指Python中提供的以双下划线开头和结尾的特殊方法,用于定义类的特殊行为,比如:init。
| 魔法方法 | 描述 |
|---|---|
__init__ | 初始化方法 |
__str__ | 字符串表示的方法 |
__eq__ | 比较两个对象是否相等(equal) |
__lt__ , __le__ , __gt__ , __ge__ | 支持比较两个对象的大小(小于(less than),小于等于(less than or equal),大于(greater than),大于等于(greater than or equal)) |
# 定义类
class Car:
def __init__(self, c_color, c_brand, c_name, c_price):
self.color = c_color
self.brand = c_brand
self.name = c_name
self.price = c_price
print("Car 类型的对象初始化完毕,对象属性已经添加完毕。")
# 魔法方法
def __str__(self):
return f"{self.color} {self.brand} {self.name} {self.price}"
def __eq__(self, other):
return self.color == other.color and self.brand == other.brand and self.name == other.name and self.price == other.price
def __lt__(self, other):
return self.price < other.price
def __le__(self, other):
return self.price <= other.price
def __gt__(self, other):
return self.price > other.price
def __ge__(self, other):
return self.price >= other.price
# 创建对象
c1 = Car("红色", "BMW", "X7", 8000000)
c2 = Car("红色", "BMW", "X7", 8000000)
print(c1 == c2)
print(c1 < c2)
print(c1 <= c2)
print(c1 > c2)
print(c1 >= c2)
属性:
- 实例属性:实例属性属于每个具体对象的属性,每个对象都是独立的。(各个对象特有的数据)
- 类属性:类属性是属于类本身的属性,所有实例共享的。(所有对象共享的数据或配置)
# 定义类
class Car:
# 类属性(所有实例属性共享)
wheel = 4 # 轮胎的数量
tax_rate = 0.1 # 购置税税率
def __init__(self, c_color, c_brand, c_name, c_price):
# 实例属性
self.color = c_color
self.brand = c_brand
self.name = c_name
self.price = c_price
self.wheel = 2
# 创建对象
c1 = Car("红色", "BMW", "X7", 8000000)
print(c1.wheel) # 优先查找实例属性有没有wheel的值,如果没有再查找类属性
# 通过类名访问类属性
print(Car.wheel)
案例:采用面向对象的编程思想,完成教务管理系统的开发。教务管理系统可以管理在校学生的成绩信息,通过控制台菜单与用户交互,具体的功能如下:
- 添加学生成绩:根据输入的学生姓名、语文成绩、数学成绩、英语成绩,记录在系统中
- 修改学生成绩:根据输入的学生姓名,修改对应的学生成绩
- 删除学生成绩:根据输入的学生姓名,删除对应的学生成绩
- 查询指定学生成绩:根据输入的学生姓名,查找对应的学生成绩,并输出
- 展示全部学生成绩:展示出系统中所有学生的成绩
# 学生类
class Student:
def __init__(self, name, chinese, math, english):
self.name = name
self.chinese = chinese
self.math = math
self.english = english
def __str__(self):
return f"姓名:{self.name} | 语文:{self.chinese} | 数学:{self.math} | 英语:{self.english} | 总分:{self.chinese + self.math + self.english}"
# 修改学生成绩
def update_score(self, chinese = None, math = None, english = None):
if chinese is not None:
self.chinese = chinese
if math is not None:
self.math = math
if english is not None:
self.english = english
# 教务系统管理类
class EduManagement:
system_version = "1.0.0"
system_name = "教务管理系统"
def __init__(self):
self.student_list = [] # 在校学生的成绩列表
# 添加学生成绩
def add_student(self):
name = input("请输入学生姓名:")
# 判断学生姓名是否存在,如果存在则添加失败
for s in self.student_list:
if s.name == name:
print("该学生已经存在,添加失败!")
return
chinese = int(input("请输入学生语文成绩:"))
math = int(input("请输入学生数学成绩:"))
english = int(input("请输入学生英语成绩:"))
# 判断分数是否在0 - 100之间
if 0 <= chinese <= 100 and 0 <= math <= 100 and 0 <= english <= 100:
stu = Student(name, chinese, math, english)
self.student_list.append(stu)
print("学生信息添加成功!")
else:
print("学生成绩必须在0 - 100之间!")
# 修改学生成绩
def update_student(self):
name = input("请输入要修改的学生姓名:")
# 判断学生姓名是否存在,如果不存在则修改失败
for s in self.student_list:
if s.name == name:
print(f"当前成绩:{s}")
chinese = int(input("请输入修改后的语文成绩:"))
math = int(input("请输入修改后的数学成绩:"))
english = int(input("请输入修改后的英语成绩:"))
# 判断分数是否在0 - 100之间
if 0 <= chinese <= 100 and 0 <= math <= 100 and 0 <= english <= 100:
s.update_score(chinese, math, english)
print("成绩修改成功!")
print(f"修改后的成绩为{s}")
return
else:
print("学生成绩必须在0 - 100之间!")
return
print("未找到该学生,修改失败!")
# 删除学生成绩
def deltet_student(self):
name = input("请输入要删除的学生姓名:")
# 判断学生姓名是否存在,如果不存在则删除失败
for s in self.student_list:
if s.name == name:
self.student_list.remove(s)
print("学生信息删除成功!")
return
print("未找到该学生,删除失败!")
# 查询学生成绩
def query_student(self):
name = input("请输入要查询的学生姓名:")
# 判断学生姓名是否存在,如果不存在则查询失败
for s in self.student_list:
if s.name == name:
print(f"学生信息:{s}")
return
print("未找到该学生,查询失败!")
# 展示全部学生信息、
def list_student(self):
for s in self.student_list:
print(s)
# 运行系统
def run(self):
print(f"欢迎使用教务管理系统V{self.system_version}!")
while True:
print()
print("# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #")
print("# 1.添加学生 2.修改学生 3.删除学生 4.查询指定学生 5.查询所有学生 6.退出系统 #")
print("# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #")
choice = input("\n请选择要执行的操作,1 - 6:")
try:
match choice:
case "1": # 添加学生
self.add_student()
case "2": # 修改学生
self.update_student()
case "3": # 删除学生
self.deltet_student()
case "4": # 查询指定学生
self.query_student()
case "5": # 查询所有学生
self.list_student()
case "6": # 退出系统
print("退出成功!")
break
case _: # 其他情况
print("输入错误,请选择1 - 6之间的菜单功能!")
except Exception as e:
print(f"程序运行出错,请重新输入代码!异常信息:{e}")
# 测试
if __name__ == "__main__":
edu_management = EduManagement()
edu_management.run()
异常
异常(也称为Bug)就是程序运行过程中出现的错误,它会中断程序的正常执行流程。
程序运行过程中出现异常,有两种处理方案:
- 不做处理:整个程序因为一个Bug,中断执行。
- 捕获异常:按照我们自己的处理方式,处理完异常,程序继续执行。
# 异常处理格式
try:
可能出现异常的业务代码1
可能出现异常的业务代码2
...
except [异常类型 as 变量名]:
出现异常时的预案
finally: # finally可写可不写
不管是否出现异常,都会执行的代码
# 异常处理
try:
print("===========================================")
print(my_name)
print(1 / 0)
print("===========================================")
except NameError as e:
print(f"程序运行出错,请联系管理员!异常信息:{e}")
except ZeroDivisionError as e:
print(f"程序运行出错,请联系管理员!异常信息:{e}")
except Exception as e: # 捕获所有异常
print(f"程序运行出错,请联系管理员!异常信息:{e}")
finally: # 无论程序是否正常运行,finally都会执行
print("资源释放~")
异常传递就是异常在函数调用中层层上报的过程,直到有人处理它,或者程序崩溃。
# 异常的传递
def fun1():
print("fun1...running...")
fun2()
def fun2():
print("fun2...running...")
fun3()
def fun3():
print("fun3...running...")
print(my_name)
if __name__ == "__main__":
try:
fun1()
except Exception as e:
print(f"程序运行出错,请联系管理员!异常信息:{e}")
