Python 第三方库实战:键盘监听鼓励器与学生管理系统
使用 pynput 和 playsound 库实现键盘监听功能,当按键达到设定次数时播放音频鼓励开发者。构建命令行学生管理系统,包含增删查改功能,利用文件读写实现数据持久化存档与读档,并使用 pyinstaller 将 Python 脚本打包为独立 exe 程序以便分发。

使用 pynput 和 playsound 库实现键盘监听功能,当按键达到设定次数时播放音频鼓励开发者。构建命令行学生管理系统,包含增删查改功能,利用文件读写实现数据持久化存档与读档,并使用 pyinstaller 将 Python 脚本打包为独立 exe 程序以便分发。

有些公司会设有程序猿鼓励师这样一个岗位,程序猿敲代码很辛苦,需要鼓励。如果公司没有这样的岗位,可以自己实现这个功能。
监听键盘按键,每按键一定次数,就自动播放一个音频,鼓励一下辛苦搬砖的自己。
pynput 用于监听键盘按键,注意版本不要用最新。playsound 用于播放音频。pip install pynput==1.6.8
pip install playsound==1.2.2
此处准备了一个 ding.mp3 放到和 py 代码同级目录中。
from import 的格式直接导入模块中的指定对象/函数。keyboard.Listener 监听键盘按键,其中 on_release 会在释放按键时被调用。listener.start 启动监听器。为了防止程序直接退出,使用 listener.join 让程序等待用户按键。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()
运行一下程序,即可感受到效果。
上述代码在执行过程中,会感觉到播放音频会导致按键卡顿,可以使用多线程解决这个问题。
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()
listener = keyboard.Listener(on_release=on_release)
listener.start()
listener.join()
先搞几个音频文件到专门的目录底下,像音频这些就被称为 资源文件。
我们用前面介绍的两个命令,先在 pip 把两个可执行文件下载一下。
写了代码之后,我们测试一下代码实现的键盘按键动作捕获功能能不能成功。
可以捕获到用户的键盘按键动作。
# 程序员鼓励师
# 播放一个音频
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('sound/1.mp3')
listener = keyboard.Listener(on_release=onRelease)
listener.start()
listener.join()
# 程序员鼓励师
# 多个音频循环播放
import random
from threading import Thread
from pynput import keyboard
from playsound import playsound
soundList = ['sound/1.mp3', 'sound/2.mp3', 'sound/3.mp3']
count = 0
def onRelease(key):
print(key)
global count
count += 1
if count % 10 == 0:
i = random.randint(0, len(soundList) - 1)
t = Thread(target=playsound, args=(soundList[i],))
t.start()
listener = keyboard.Listener(on_release=onRelease)
listener.start()
listener.join()
实现一个命令行版本的学生管理系统。
students 表示所有学生信息。menu 函数和用户交互。这是一个自定义函数。insert,show,find,delete 这几个自定义函数完成增删查操作。sys.exit 实现程序退出。import sys
students = []
def main():
""" 程序的入口函数 """
print('+--------------------------+')
print('| 欢迎来带学生管理系统! |')
print('+--------------------------+')
while True:
choice = menu()
if choice == '0':
sys.exit()
elif choice == '1':
insert()
elif choice == '2':
show()
elif choice == '3':
find()
elif choice == '4':
delete()
else:
print('您的输入有误!请重新输入!')
if __name__ == '__main__':
main()
def menu():
print("1. 新增学生信息")
print("2. 显示所有同学信息")
print("3. 根据名字查找学生信息")
print("4. 删除学生信息")
print("0. 退出程序")
choice = input("请输入您的选择:")
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)
print("[新增学生] 完毕!")
def show():
print("[显示学生] 开始!")
for s in students:
print(f"[{s['studentId']}] {s['name']} {s['gender']} {s['className']}")
print(f"[显示学生] 完毕!共显示了 {len(students)} 条记录!")
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} 条记录!")
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} 条记录!")
约定存档文件放到 record.txt 文件中。
并且以行文本的方式来保存学生信息,格式如下:
学号\t名字\t性别\t班级
\t 制表符进行分隔。def save():
""" 存档函数 """
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)} 条记录!")
在 insert 和 delete 末尾,调用 save 函数进行存档。
import os.path
def load():
""" 读档函数 """
if not os.path.exists('record.txt'):
return
global students
students = []
with open('record.txt', 'r', encoding='utf8') 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 加载存档。
当前虽然已经实现了一个管理系统,但是 .py 的文件只能在安装了 Python 环境的机器上运行。
为了能够更好的部署到其他主机上,可以借助 pyinstaller 来把 Python 程序打包成 exe 程序。
pip install pyinstaller
-F 表示打包成单个 exe(不带动态库):pyinstaller -F 学生管理系统.py
稍等片刻,很快打包完成。 此时就可以把这个程序拷贝给其他机器使用了!无需 Python 环境即可运行!
整合后的完整代码示例:
import sys
students = []
def menu():
print('1. 新增学生')
print('2. 显示学生')
print('3. 查找学生')
print('4. 删除学生')
print('0. 退出程序')
choice = input('请输入您的选择:')
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)
print('【新增学生】完毕!')
def show():
print('【显示学生】开始!')
for s in students:
print(f"[{s['studentId']}] {s['name']} {s['gender']} {s['className']}")
print(f'【显示学生】完毕!共显示了{len(students)}条数据!')
def find():
print('【查找学生】开始!')
name = input('请输入要查找的同学姓名:')
count = 0
for s in students:
if name == s['name']:
print(f"[{s['studentId']}] {s['name']} {s['gender']} {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:
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('您的输入有误!请重新输入!')
if __name__ == '__main__':
main()
import os.path
import sys
students = []
def save():
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'):
return
global students
students = []
with open('record.txt', 'r', encoding='utf8') 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)}条记录!')
def menu():
print('1. 新增学生')
print('2. 显示学生')
print('3. 查找学生')
print('4. 删除学生')
print('0. 退出程序')
choice = input('请输入您的选择:')
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)
save()
print('【新增学生】完毕!')
def show():
print('【显示学生】开始!')
for s in students:
print(f"[{s['studentId']}] {s['name']} {s['gender']} {s['className']}")
print(f'【显示学生】完毕!共显示了{len(students)}条数据!')
def find():
print('【查找学生】开始!')
name = input('请输入要查找的同学姓名:')
count = 0
for s in students:
if name == s['name']:
print(f"[{s['studentId']}] {s['name']} {s['gender']} {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()
while True:
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('您的输入有误!请重新输入!')
if __name__ == '__main__':
main()
Python 经典进阶书籍,针对各种典型场景提供了一些解决方案。 这本书就像是一本菜谱,会给你罗列各种各样的场景下使用 Python 该如何解决。有助于打开解决问题的思路。
有大佬整理了 Python 的一些非常实用的程序库。
Python 的代码示例集合。比前面举的例子要丰富得多。 使用简短的 Python 代码来实现一些有意思的程序。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online