
🎬 个人主页:艾莉丝努力练剑
❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》
⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平
🎬 艾莉丝的简介:

文章目录
- 3 ~> 第三方库
-
- 3.5 代码示例:“程序猿鼓励师”
-
- 3.5.1 安装第三方依赖
- 3.5.2 准备音频文件
- 3.5.3 编写代码
- 3.5.4 改进代码
- 3.5.5 操作流程
- 3.5.6 最佳实践
-
- 3.5.6.1 播放一个音频
- 3.5.6.2 多个音频循环播放
- 4 ~> 综合案例:学生管理系统
-
- 4.1 需求说明
-
- 4.1.1 功能
- 4.2 创建入口函数
- 4.3 实现菜单函数
- 4.4 实实现增删查操作
-
- 4.4.1 新增学生
- 4.4.2 显示学生
- 4.4.3 查找学生
- 4.4.4 删除学生
- 4.5 加入存档读档
- 4.5.1 约定存档格式
-
- 4.5.2 实现存档函数
- 4.5.3 实现读档函数
- 4.6 打包成 exe 程序发布
-
- 4.6.1 安装 pyinstaller
- 4.6.2 打包程序
- 4.7 最佳实践
-
- 4.7.1 实现增删查功能
- 4.7.2 添加存档(save)和读档(load),将信息保存到硬盘上
- 5 ~> 后续扩展
-
- 5.1 python cookbook
- 5.2 awesome-python
- 5.3 500 Lines or Less
- 结尾

3 ~> 第三方库
3.5 代码示例:“程序猿鼓励师”
有些公司会设有程序猿鼓励师这样一个岗位,程序猿敲代码很辛苦,需要鼓励,一般程序猿鼓励师是一些好看的妹子,在程序猿燃尽了的时候可以鼓励程序员继续敲代码。
但是,很多公司没有这样一个岗位怎么办?程序猿自己来实现一下这个功能,自己鼓励一下自己。
监听键盘按键,每按键20下,就自动播放一个音频,鼓励一下辛苦搬砖的自己。

3.5.1 安装第三方依赖
- pynput用于监听键盘按键,注意版本不要用最新。
- playsound用于播放音频。
pip install pynput==1.6.8
pip install playsound==1.2.2
3.5.2 准备音频文件
此处准备了一个ding.mp3放到和py代码同级目录中。
3.5.3 编写代码
- 使用from import的格式直接导入模块中的指定对象/函数。
- 使用keyboard.Listener监听键盘按键,其中on_release会在释放按键时被调用。
- 使用listener.start启动监听器.为了防止程序直接退出,使用listener.join让程序等待用户按键。
- 使用count计数,每隔10次,调用playsound播放音频文件。
from pynput import keyboard
from playsound import playsound
count = 0
def on_release(key):
print(key)
global count
count += 1
if count % 10 == 0:
playsound('ding.mp3')
listener = keyboard.Listener( on_release=on_release)
listener.start()
listener.join()
运行一下程序,即可感受到效果。
3.5.4 改进代码
上述代码在执行过程中,会感觉到播放音频会导致按键卡顿,可以使用多线程解决这个问题,关于多线程的知识,在此处不详细介绍。
- 使用threading.Thread引入多线程类。
- 使用Thread的构造函数来构造一个线程,target表示线程要执行的任务,args表示target中要调用函数的参数。
- 使用Thread.start()启动线程。
from pynput import keyboard
from playsound import playsound
from threading import Thread
count = 0
def on_release(key):
print(key)
global count
count += 1
if count % 10 == 0:
t = Thread(target=playsound, args=('ding.mp3',))
t.start()
#playsound('ding.mp3')
listener = keyboard.Listener(on_release=on_release)
listener.start()
listener.join()
3.5.5 操作流程
先搞几个音频文件到专门的目录底下——


像音频这些就被称为 资源文件。

开个玩笑哈。
我们用前面介绍的两个命令,先在pip把两个可执行文件下载一下——


写了代码之后,我们测试一下代码实现的键盘按键动作捕获功能能不能成功——

可以捕获到用户的键盘按键动作。
运行——

3.5.6 最佳实践
3.5.6.1 播放一个音频
# 程序员鼓励师
# 播放一个音频
from pynput import keyboard
# 引入播放音频的模块
from playsound import playsound
# 创建一个计数器,记录当前用户按了多少次键盘
count = 0
def onRelease(key):
"""
这个函数,就是在用户释放键盘按键的时候,就会被调用到
这个函数不是咱们自己调用的,而是咱们把这个函数交给了 Listener 自己,
由这个 Listener 在用户释放按键的时候自动调用
像这样的不是我们自己主动调用,而是交给别人,在合适的时机进行调用,这样的函数,叫做“回调函数(callback function)”
:param key:用户按下了哪个键
:return:
"""
print(key)
global count
count += 1
if count % 10 == 0: # 只有按的次数是10的倍数的时候才会播放音频
# 播放一个音频!
# playsound('python_code/sound/1.mp3') # 传入的参数就是要播放的文件名
playsound('D:/Python_code/python_code/sound/1.mp3') # 替换为实际完整路径
# 当我们创建好 listener 之后,用户的键盘按键动作就会被捕获到
# 我们还希望捕获到之后能够执行一段代码
listener = keyboard.Listener(on_release=onRelease)
# 这个操作不是在进行调用,而是把函数名当成了一个变量传到了 Listener 里面,具体什么时候调用,由 Listener 自己决定
# 所谓的“自己决定”就是会说它会检测键盘什么时候释放,释放,就执行,不释放就不执行
listener.start()
listener.join()
3.5.6.2 多个音频循环播放
# 程序员鼓励师
# 多个音频循环播放
import random
from threading import Thread
from pynput import keyboard
# 引入播放音频的模块
from playsound import playsound
soundList = ['D:/Python_code/python_code/sound/1.mp3','D:/Python_code/python_code/sound/2.mp3','D:/Python_code/python_code/sound/3.mp3']
# 创建一个计数器,记录当前用户按了多少次键盘
count = 0
def onRelease(key):
"""
这个函数,就是在用户释放键盘按键的时候,就会被调用到
这个函数不是咱们自己调用的,而是咱们把这个函数交给了 Listener 自己,
由这个 Listener 在用户释放按键的时候自动调用
像这样的不是我们自己主动调用,而是交给别人,在合适的时机进行调用,这样的函数,叫做“回调函数(callback function)”
:param key:用户按下了哪个键
:return:
"""
print(key)
global count
count += 1
if count % 10 == 0: # 只有按的次数是10的倍数的时候才会播放音频
# 如果感觉播放得太频繁了,吵到耳朵了,也可以适当降低一下频率,把除余的数字改大一点
# 播放音频!
# 先生成随机数
i = random.randint(0,len(soundList) – 1)
# 此处的播放音频,消耗时间比较多,可能会引起输入的卡顿(不流畅)
# 可以创建一个线程,在线程里面播放音频!
# playsound(soundList[i]) # 传入的参数就是要播放的文件名
t = Thread(target=playsound,args=(soundList[i],)) # 在一个新的线程里面完成播放音频
# (新的线程可以想象成一个新的执行流)
# 上面这里只是给线程安排任务,下面才是创建了一个线程出来
t.start()
# 当我们创建好 listener 之后,用户的键盘按键动作就会被捕获到
# 我们还希望捕获到之后能够执行一段代码
listener = keyboard.Listener(on_release=onRelease)
# 这个操作不是在进行调用,而是把函数名当成了一个变量传到了 Listener 里面,具体什么时候调用,由 Listener 自己决定
# 所谓的“自己决定”就是会说它会检测键盘什么时候释放,释放,就执行,不释放就不执行
listener.start()
listener.join()
# 编写一段代码,感受一下这个程序的效果
# 播放音频可能出现卡顿
# 再次感受下代码的效果,此时感觉就流畅了!
# 现在是把频率降低到 xx 下播放一次,感觉好不少啦!
4 ~> 综合案例:学生管理系统
4.1 需求说明
实现一个命令行版本的学生管理系统。
4.1.1 功能

4.2 创建入口函数
- 使用一个全局列表 students 表示所有学生信息。
- 使用 menu 函数和用户交互. 这是一个自定义函数。
- 使用 insert, show ,find,delete 这几个自定义函数完成增删查操作。
- 使用 sys.exit 实现程序退出。
# 使用列表表示所有的学生
students = []
def main():
"""
程序的入口函数
"""
print('+————————–+')
print('| 欢迎来带学生管理系统! |')
print('+————————–+')
while True:
choice = menu()
if choice == 0 :
sys.exit()
if choice == 1 :
insert()
elif choice == 2 :
show()
elif choice == 3 :
find()
elif choice == 4 :
delete()
else:
print('您的输入有误!请重新输入!')
main()
4.3 实现菜单函数
def menu():
print("1. 新增学生信息")
print("2. 显示所有同学信息")
print("3. 根据名字查找学生信息")
print("4. 删除学生信息")
print("0. 退出程序")
choice = input("请输入您的选择:")
return int(choice)
4.4 实实现增删查操作
4.4.1 新增学生
```python
def insert():
print("[新增学生] 开始!");
studentId = input("请输入学生的学号: ")
name = input("请输入学生的姓名: ")
gender = input("请输入学生的性别: ")
if gender not in ('男', '女');
print("性别不符合要求!新增学生失败!");
return
className = input("请输入学生的班级: ")
# 使用一个字典表示学生信息
student = {
'studentId': studentId,
'name': name,
'gender': gender,
'className': className
}
# 把字典添加到学生列表中
global students
students.append(student)
print("[新增学生] 完毕!");
4.4.2 显示学生
def show():
print("[显示学生] 开始!");
for s in students:
print(f"[{s['studentId']}]\\t{s['name']}\\t{s['gender']}\\t{s['className']}")
print(f"[显示学生] 完毕! 共显示了 {len(students)} 条记录!")
4.4.3 查找学生
def find():
print("[查找学生] 开始!");
name = input("请输入要查找的同学姓名:")
count = 0
for s in students:
if name == s['name'];
print(f"[{s['studentId']}] \\t{s['name']} \\t{s['gender']} \\t{s['className']}")
count += 1
print(f"[查找学生] 完毕!共查找到 {count} 条记录!")
4.4.4 删除学生
def delete():
print("[删除学生] 开始!");
studentId = input("请输入要删除的同学学号: ");
count = 0
for s in students:
if studentId == s['studentId'];
print(f"删除 {s['name']} 同学的信息!");
students.remove(s)
count += 1
print(f"[删除学生] 完毕!共删除 {count} 条记录!");
4.5 加入存档读档
4.5.1 约定存档格式
约定存档文件放到d:/record.txt文件中。
并且以行文本的方式来保存学生信息,格式如下:
学号\\t名字\\t性别\\t班级 学号\\t名字\\t性别\\t班级 学号\\t名字\\t性别\\t班级
- 每个同学占一行。
- 每个同学的信息之间使用\\t制表符进行分隔。
4.5.2 实现存档函数
def save():
"""
存档函数
"""
with open('d:/record.txt', 'w') as f:
for s in students:
f.write(f"{s['studentId']} \\t{s['name']} \\t{s['gender']} \\t{s['className']} \\n")
print(f"存档成功!共存储了 {len(students)} 条记录!")
在insert和delete末尾,调用save函数进行存档。
# 执行存档
save()
4.5.3 实现读档函数
def load():
"""
读档函数
"""
# 如果存档文件不存在,则跳过读档环节
if not os.path.exists('d:/record.txt');
return
# 先清空全局变量里的数据
global students
students = []
with open('d:/record.txt', 'r') as f:
for line in f:
# 去除末尾的换行符
line = line.strip()
tokens = line.split('\\t')
if len(tokens) < 4:
print(f"文件格式有误!line={line}")
continue
student = {
'studentId': tokens[0],
'name': tokens[1],
'gender': tokens[2],
'className': tokens[3]
}
students.append(student)
print(f"[读档成功] 共读取了 {len(students)} 条记录!")
在main函数开头的地方,调用load加载存档:
load()
4.6 打包成 exe 程序发布
当前虽然已经实现了一个管理系统,但是.py的文件只能在安装了Python环境的机器上运行。
为了能够更好的部署到其他主机上,可以借助pyinstaller来把Python程序打包成exe程序。
4.6.1 安装 pyinstaller
pip install pyinstaller
4.6.2 打包程序
- -F表示打包成单个exe(不带动态库):
pyinstall -F 学生管理系统.py
注意:如果提示找不到pyinstaller命令,则需要重启一下PyCharm。
稍等片刻,很快打包完成。

图标效果如下所示——

此时就可以把这个程序拷贝给其他机器使用了!无需Python环境即可运行!
4.7 最佳实践

使用这样的格式进行区分——


4.7.1 实现增删查功能
# 实现一个命令行版本的学生管理系统
import sys
# 使用这个全局变量,来管理所有的学生信息
# 这个列表的每个元素都是一个“字典”,每个字典就分别表示了一个同学!
students = [] # 数据保存在这样一个变量里面,变量容易丢失数据,为了持续保存,需要存在一个文件里面
def menu():
print('1. 新增学生')
print('2. 显示学生')
print('3. 查找学生')
print('4. 删除学生')
print('0. 退出程序')
choice = input('请输入您的选择: ')
# return int(choice) # 转成选项
# 或者直接以字符串的形式
return choice
# 实现增删查功能
def insert():
print('【新增学生】开始!')
studentID = input('请输入学生的学号:')
name = input('请输入学生的姓名:')
gender = input('请输入学生的性别:')
if gender not in('男,女'):
print('性别输入的内容不符合要求,新增失败!')
return
className = input('请输入学生的班级:')
# 使用一个字典把上述的信息给聚合起来
student = {
'studentId':studentID,
'name':name,
'gender':gender,
'className':className
}
global students
students.append(student) # 通过 append 新增学生
print('【新增学生】完毕!')
def show():
# 遍历全局变量的这个列表,把每个学生的信息打印出来
print('【显示学生】开始!')
for s in students:
print(f"[{s['studentId']}]\\t{s['name']}\\t{s['gender']}\\t{s['className']}") # 通过制表符分隔开
print(f'【显示学生】完毕!共显示了{len(students)}条数据!')
def find():
# 改进学生姓名,来进行查找
print('【查找学生】开始!')
name = input('请输入要查找的同学姓名: ')
count = 0
for s in students: # students(全局变量),读取全局变量的时候不需要加 global 去修饰,修改时才需要加
if name == s['name']:
print(f"[{s['studentId']}]\\t{s['name']}\\t{s['gender']}\\t{s['className']}")
count += 1
print(f'【查找学生】结束!共找到了{count}个匹配的同学!')
def delete():
print('【删除学生】开始!')
studentId = input('请输入要删除的学生学号:')
# 看看这个学号对应的同学是哪个字典,然后把这个字典从列表里面删掉就好了
for s in students:
if studentId == s['studentId']:
print(f"删除{s['name']}同学的信息!")
students.remove(s)
print('【删除学生】完毕!')
def main():
"""
入口函数
"""
# 通过控制台和用户进行交互
print('———————————————–')
print(' 欢迎来到学生管理系统 ')
print('———————————————–')
while True:
# 通过 menu 函数来打印出菜单项
choice = menu()
if choice == '1':
# 新增学生
insert()
elif choice == '2':
# 显示所有学生
show()
elif choice == '3':
# 查找学生
find()
elif choice == '4':
# 删除学生
delete()
elif choice == '0':
# 退出程序
print('goodbye!')
sys.exit(0)
else:
print('您的输入有误!请重新输入!')
# 需要进入下次循环,让用户重新输入
# continue
# 存储在内存里面的数据是容易丢失的!
main()
4.7.2 添加存档(save)和读档(load),将信息保存到硬盘上

# 实现一个命令行版本的学生管理系统
import os.path
import sys
# 使用这个全局变量,来管理所有的学生信息
# 这个列表的每个元素都是一个“字典”,每个字典就分别表示了一个同学!
students = []
# 硬盘可以持久化存储数据!
def save(): # 保存操作
"""
用于存档
"""
# 使用上下文管理器
# 此处的路径不是以d: 开头的“绝对路径”,而是相对路径
# 此时这个写法的含义就是让 record.txt 和 当前的 code77.py 在同一个目录里
with open('record.txt','w',encoding='utf8')as f: # 直接写了文件名,没有写前面的路径(绝对路径)
for s in students:
f.write(f"{s['studentId']}\\t{s['name']}\\t{s['gender']}\\t{s['className']}\\n")
print(f'【存档成功】共存储了{len(students)}条记录!')
def load(): # 读档操作
"""
用于读档
"""
# 如果读档文件不存在,则直接跳过读档流程
# 判断文件是否存在
# 为了避免读方式打开文件的时候,文件不存在的情况
if not os.path.exists('record.txt'): # path 这个模块可以帮我们进行一些路径上的判定操作
return
# 读档的时候要保证把旧的数据给清理干净!
global students
students = [] # 把列表置为空
with open('record.txt','r',encoding='utf8')as f:
for line in f: # 按行读取文件
# 针对这一行数据,按照 \\t 进行切分操作!
# 切分之前要去除末尾的换行,怎么去除?
line = line.strip() # strip这是一个非常有用的方法,它的功能是:去掉一个字符串开头和末尾的空白符
# 空白符:空格、换行、回车、制表符、翻页符、垂直制表符……
tokens = line.split('\\t')
if len(tokens) != 4:
print(f'当前行格式存在问题!line={line}')
continue
student = {
'studentId':tokens[0],
'name':tokens[1],
'gender':tokens[2],
'className':tokens[3]
}
students.append(student)
print(f'【读档成功】共读取了{len(students)}条记录!')
def menu():
print('1. 新增学生')
print('2. 显示学生')
print('3. 查找学生')
print('4. 删除学生')
print('0. 退出程序')
choice = input('请输入您的选择: ')
# return int(choice) # 转成选项
# 或者直接以字符串的形式
return choice
# 实现增删查功能
def insert():
print('【新增学生】开始!')
studentID = input('请输入学生的学号:')
name = input('请输入学生的姓名:')
gender = input('请输入学生的性别:')
if gender not in('男,女'):
print('性别输入的内容不符合要求,新增失败!')
return
className = input('请输入学生的班级:')
# 使用一个字典把上述的信息给聚合起来
student = {
'studentId':studentID,
'name':name,
'gender':gender,
'className':className
}
global students
students.append(student) # 通过 append 新增学生
# 增加保存操作
save()
print('【新增学生】完毕!')
def show():
# 遍历全局变量的这个列表,把每个学生的信息打印出来
print('【显示学生】开始!')
for s in students:
print(f"[{s['studentId']}]\\t{s['name']}\\t{s['gender']}\\t{s['className']}") # 通过制表符分隔开
print(f'【显示学生】完毕!共显示了{len(students)}条数据!')
def find():
# 改进学生姓名,来进行查找
print('【查找学生】开始!')
name = input('请输入要查找的同学姓名: ')
count = 0
for s in students: # students(全局变量),读取全局变量的时候不需要加 global 去修饰,修改时才需要加
if name == s['name']:
print(f"[{s['studentId']}]\\t{s['name']}\\t{s['gender']}\\t{s['className']}")
count += 1
print(f'【查找学生】结束!共找到了{count}个匹配的同学!')
def delete():
print('【删除学生】开始!')
studentId = input('请输入要删除的学生学号:')
# 看看这个学号对应的同学是哪个字典,然后把这个字典从列表里面删掉就好了
for s in students:
if studentId == s['studentId']:
print(f"删除{s['name']}同学的信息!")
students.remove(s)
# 涉及修改,增加保存操作
save()
print('【删除学生】完毕!')
def main():
"""
入口函数
"""
# 通过控制台和用户进行交互
print('———————————————–')
print(' 欢迎来到学生管理系统 ')
print('———————————————–')
# 需要在程序启动的时候调用 load 即可(最开始加载一次,就不用反复加载了)
load()
while True:
# 通过 menu 函数来打印出菜单项
choice = menu()
if choice == '1':
# 新增学生
insert()
elif choice == '2':
# 显示所有学生
show()
elif choice == '3':
# 查找学生
find()
elif choice == '4':
# 删除学生
delete()
elif choice == '0':
# 退出程序
print('goodbye!')
sys.exit(0)
else:
print('您的输入有误!请重新输入!')
# 需要进入下次循环,让用户重新输入
# continue
# 存储在内存里面的数据是容易丢失的!
main()

运行一下,结果如下所示——

5 ~> 后续扩展
5.1 python cookbook
python经典进阶书籍,针对各种典型场景提供了一些解决方案。

这本书就像是一本菜谱,会给你罗列各种各样的场景下使用Python该如何解决。有助于打开解决问题的思路。
5.2 awesome-python
有大佬整理了Python的一些非常实用的程序库,这里挂了大佬的码云链接:awesome-python
5.3 500 Lines or Less
Python的代码示例集合。比艾莉丝前面举的例子要丰富得多。
使用简短的Python代码来实现一些有意思的程序,下面是其Github的链接:500 Lines or Less
结尾
uu们,本文的内容到这里就全部结束了,艾莉丝再次感谢您的阅读!
结语:希望对学习Python相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!
往期回顾:
【Python库和代码案例:第一课】Python 标准库与第三方库实战指南:从日期处理到 Excel 操作
🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡
૮₍ ˶ ˊ ᴥ ˋ˶₎ა




