windows需交互式用户会话才能用win10toast;macos应使用pyobjc而非applescript以确保通知归属明确;linux用notify-send但注意桌面环境差异;定时通知推荐apscheduler而非schedule。

Windows 用 win10toast 最快,但别在服务进程里调它
它依赖 Windows 的 Toast Notification API,必须运行在有桌面会话的用户上下文中。如果你把脚本丢进 Windows 服务、计划任务(以 SYSTEM 身份运行)或远程桌面断开后的后台,show_toast() 会静默失败,不报错也不显示——这是最常被卡住的地方。
- 只在交互式登录用户下运行才可靠(比如你本人开着电脑、没锁屏)
- 计划任务要勾选“不管用户是否登录都要运行” → 改用
subprocess.run(["msg", "*"])或写入事件日志 + 配合 PowerShell 弹窗 -
duration参数不是强制停留时间:设成5,用户手动点击关闭,它就立刻消失;设成0则由系统决定(通常 7 秒) - 图标路径必须是绝对路径,且文件存在,否则回退到默认图标,不报错
macOS 原生通知得靠 pyobjc,别信“一行命令”
网上很多教程说 osascript -e 'display notification' 就能发通知,确实能,但它走的是 AppleScript 桥接层,无法设置应用标识(app_id),导致所有通知都归到“Terminal”,点进去打不开你的程序,历史记录也混在一起。
- 真正可控的方式是用
pyobjc调NSUserNotificationCenter,这样通知带图标、可点击、归属明确 - 安装时注意:macOS 14+(Sequoia)需用 Python 3.9+,且
pip install pyobjc必须完整安装,不能只装子模块 - 通知内容里别直接拼接用户输入:
message中含单引号或反斜杠可能触发 Objective-C 字符串解析异常,先用message.replace("'", "’")简单转义
Linux 用 notify-send 最稳,但 GNOME/KDE 行为不一致
subprocess.run(["notify-send", "标题", "内容"]) 是事实标准,不依赖 Python 库,服务器桌面环境也能跑。但它背后是 D-Bus 协议,而 GNOME 和 KDE 对超时、图标、动作按钮的支持程度不同。
- GNOME 默认忽略
-t(超时毫秒)参数,实际显示时长由系统设置控制(通常 3–5 秒);KDE 则严格按-t 5000执行 - 图标名写错(如
-i face-smile但系统没这个图标主题)→ GNOME 显示空白方块,KDE 直接静默丢弃整条通知 - 想让通知点击后执行命令?加
--action="default=打开",但只有 GNOME 42+ 和 KDE Plasma 5.27+ 支持,旧版本无效
定时通知别硬套 schedule,APScheduler 才扛得住 cron 场景
schedule 的 every().day.at("09:00") 看着简单,但一旦机器休眠、时间跳变(如 NTP 校时)、或脚本中途崩溃,它就彻底失联——没有持久化、无错重试、不支持时区。
- 真正需要“每天上午 9 点准时提醒”的场景,请用
APScheduler的CronTrigger(hour=9, minute=0, timezone="Asia/Shanghai") - 启动时加
job_defaults={"coalesce": True, "max_instances": 1},防止休眠唤醒后一堆通知扎堆弹出 - 不要在
add_job()里传 lambda 或闭包函数:APScheduler 序列化 job 时会失败,必须用模块级函数名
跨平台通知最难的不是发出去,而是“发给谁、什么时候能看见、点了之后去哪”。图标路径、用户会话、D-Bus 总线状态、cron 时区……这些细节不显眼,但一漏就整个通知链失效。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











