跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

Python 第三方库实战:键盘监听与学生管理系统

Python 第三方库实战教程。通过 pynput 和 playsound 实现键盘监听自动播放音频的“程序员鼓励师”功能,结合多线程优化体验。随后构建命令行版学生管理系统,涵盖增删查改、文件存档读档及 PyInstaller 打包发布流程,提供完整代码示例与最佳实践。

橘子海发布于 2026/2/5更新于 2026/5/302.8K 浏览
Python 第三方库实战:键盘监听与学生管理系统

Python 第三方库实战:键盘监听与学生管理系统

3. 第三方库

3.5 代码示例:'程序猿鼓励师'

有些公司会设有程序猿鼓励师这样一个岗位,程序猿敲代码很辛苦,需要鼓励。很多公司没有这样一个岗位怎么办?程序猿自己来实现一下这个功能,自己鼓励一下自己。

监听键盘按键,每按键一定次数,就自动播放一个音频,鼓励一下辛苦搬砖的自己。

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()

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('D:/Python_code/python_code/sound/1.mp3')
        # 替换为实际完整路径

# 当我们创建好 listener 之后,用户的键盘按键动作就会被捕获到
# 我们还希望捕获到之后能够执行一段代码
listener = keyboard.Listener(on_release=onRelease)
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):
    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()

4. 综合案例:学生管理系统

4.1 需求说明

实现一个命令行版本的学生管理系统。

4.1.1 功能
  1. 新增学生信息
  2. 显示所有同学信息
  3. 根据名字查找学生信息
  4. 删除学生信息
  5. 退出程序

4.2 创建入口函数

  • 使用一个全局列表 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('您的输入有误!请重新输入!')

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 新增学生
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']}]	{s['name']}	{s['gender']}	{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 制表符进行分隔。
4.5.2 实现存档函数
def save():
    """存档函数"""
    with open('d:/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 函数进行存档。

4.5.3 实现读档函数
import os.path

def load():
    """读档函数"""
    # 如果存档文件不存在,则跳过读档环节
    if not os.path.exists('d:/record.txt'):
        return
    # 先清空全局变量里的数据
    global students
    students = []
    with open('d:/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 加载存档。

4.6 打包成 exe 程序发布

当前虽然已经实现了一个管理系统,但是 .py 的文件只能在安装了 Python 环境的机器上运行。 为了能够更好的部署到其他主机上,可以借助 pyinstaller 来把 Python 程序打包成 exe 程序。

4.6.1 安装 pyinstaller
pip install pyinstaller
4.6.2 打包程序
  • -F 表示打包成单个 exe(不带动态库):
pyinstaller -F 学生管理系统.py

稍等片刻,很快打包完成。 此时就可以把这个程序拷贝给其他机器使用了!无需 Python 环境即可运行!

4.7 最佳实践

4.7.1 实现增删查功能
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']}]\t{s['name']}\t{s['gender']}\t{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('请输入要删除的学生学号:')
    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('您的输入有误!请重新输入!')

main()
4.7.2 添加存档(save)和读档(load),将信息保存到硬盘上
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']}]\t{s['name']}\t{s['gender']}\t{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('请输入要删除的学生学号:')
    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('您的输入有误!请重新输入!')

main()

5. 后续扩展

5.1 python cookbook

Python 经典进阶书籍,针对各种典型场景提供了一些解决方案。 这本书就像是一本菜谱,会给你罗列各种各样的场景下使用 Python 该如何解决。有助于打开解决问题的思路。

5.2 awesome-python

有大佬整理了 Python 的一些非常实用的程序库。

5.3 500 Lines or Less

Python 的代码示例集合。比前面举的例子要丰富得多。 使用简短的 Python 代码来实现一些有意思的程序。

目录

  1. Python 第三方库实战:键盘监听与学生管理系统
  2. 3. 第三方库
  3. 3.5 代码示例:“程序猿鼓励师”
  4. 3.5.1 安装第三方依赖
  5. 3.5.2 准备音频文件
  6. 3.5.3 编写代码
  7. 3.5.4 改进代码
  8. 3.5.5 操作流程
  9. 3.5.6 最佳实践
  10. 3.5.6.1 播放一个音频
  11. 程序员鼓励师
  12. 播放一个音频
  13. 当我们创建好 listener 之后,用户的键盘按键动作就会被捕获到
  14. 我们还希望捕获到之后能够执行一段代码
  15. 3.5.6.2 多个音频循环播放
  16. 程序员鼓励师
  17. 多个音频循环播放
  18. 4. 综合案例:学生管理系统
  19. 4.1 需求说明
  20. 4.1.1 功能
  21. 4.2 创建入口函数
  22. 4.3 实现菜单函数
  23. 4.4 实现增删查操作
  24. 4.4.1 新增学生
  25. 4.4.2 显示学生
  26. 4.4.3 查找学生
  27. 4.4.4 删除学生
  28. 4.5 加入存档读档
  29. 4.5.1 约定存档格式
  30. 4.5.2 实现存档函数
  31. 4.5.3 实现读档函数
  32. 4.6 打包成 exe 程序发布
  33. 4.6.1 安装 pyinstaller
  34. 4.6.2 打包程序
  35. 4.7 最佳实践
  36. 4.7.1 实现增删查功能
  37. 4.7.2 添加存档(save)和读档(load),将信息保存到硬盘上
  38. 5. 后续扩展
  39. 5.1 python cookbook
  40. 5.2 awesome-python
  41. 5.3 500 Lines or Less
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 无线联邦学习:隐私保护下的分布式 AI 协同机制
  • OpenAI 官宣结构化输出功能及常用工具汇总
  • 基于 Scrapy 的论坛帖子内容抓取实战教程
  • 生成式人工智能与大语言模型在医疗保健领域的全面融合路线图
  • RTX 5060 Ti Linux 驱动黑屏解决方案:BIOS 设置与 Open Kernel 配置
  • 鸿蒙车载互联实战:用分布式技术重构出行体验
  • Canon EOS DIGITAL Info - 佳能 EOS DSLR 信息读取与编辑工具
  • 本地 Docker 部署 Appsmith 及远程访问配置指南
  • Coze(扣子)100 个落地用途与发布使用指南
  • ELKJS:JavaScript 节点图自动布局方案详解
  • 2025 开源供应链投毒分析技术报告
  • GitHub 国内镜像站与加速方案汇总
  • HTB Eighteen 靶机实战:MSSQL 渗透至 BadSuccessor 域控接管
  • llama.cpp 部署 Qwen3-14B-Claude-4.5-Opus-High-Reasoning-Distill 模型
  • AFFiNE 开源全能知识工作空间使用指南
  • 基于STM32的智能小车避障与循迹实战
  • RMBG-2.0 企业级集成:API 封装、Flask 后端与前端拖拽上传方案
  • 国内主流 AI 工具对比:豆包、元宝、千问、Kimi、DeepSeek、MiniMax、GLM
  • MCP Server Node.js 开发环境搭建与部署指南
  • Whisper 模型版本及下载链接

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online