玩转psutil 教你用Python检测U盘插入和拔出
1、开始之前,请确保小伙伴具备以下知识:
Python的基础知识(包括切片、引用全局变量、循环等等基础知识)
如有不懂,或者是需要这份代码。请在经验底部给小编投票或有得留言,小编看到会第一时间回复。
另外经验引用是一些附加知识,它可以帮助你快速开发出这样的程序。
并且确保电脑中装有psutil包。
查看的方法如下:
打开cmd命令提示符:pip list | find "psutil"

2、思路分析:
我们通过psutil包内的disk_partitions()方法获得驱动器数(或者说是分区数,windows上完全可以这样理解)
disk_partitions()会返回一个对象列表(列表内的有M个sdiskpart对象)
它们的格式如下:
[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'),.....]
我们可以看到这样一个列表,里面有多个(磁盘驱动器数)对象。
sdiskpart对象有以下属性:
device:驱动器(可以理解为分区)
mountpoint:挂载点 (也可以理解为分区,Windows上都是一样的)
fstype:文件类型
opts:挂载选项(如果小伙伴学过linux的mount,对这个肯定不陌生,可以理解为它的权限和信息)
详情可以参考下经验引用(玩转psutil:教你怎么用Python获得分区个数)

3、我们得到了驱动器个数之后,我们必须要知道驱动器是什么类型的,以此来区分是我们的硬盘还是我们的U盘,或者是网络映射还是光盘之类的。
我们可以通过opts属性来分析,我们上面也说过,opts是一个驱动器在挂载时被设定的参数,例如opts='rw,fixed'
rw参数意味着可读可写,而fixed说明它是一个本地驱动器(查查这个单词就知道了)
再来看看这个:opts='rw,removable'
这个removable是意思是:可移动的,可拆的
这就可以让我们区分硬盘和U盘
那么,我们有了驱动器个数,并且知道怎么区分驱动类型之后,我们就可以通过一个循环,不断的获取驱动器个数,如果发现驱动器个数少于之前,便是拔出,驱动器多于之前便是插入。
对不对??
OK。开始写我们的代码。
import psutil
import time,sys
from win32gui import MessageBox as box
#/*
# * ---全局数据 实时更新
# */
local_device = [] #本地驱动器
local_letter = [] #本地盘符
local_number = 0 #本地驱动器数
mobile_device = [] #移动设备
mobile_letter = [] #移动设备盘符
mobile_number = 0 #移动设备数
这里我们用到了一个windows API函数MessageBox,调用提示框用,不用tkinter的原因是因为tkinter只为了画一个提示框,相当不方便。
有关这个函数请参考百科MessageBox或者MSDN

4、定义一个函数,用于更新数据(也就是上面定义的几个全局变量的数据),返回驱动器数量
def updata():
global local_device,local_letter,local_number,\
mobile_device,mobile_letter,mobile_number
#引入全局变量
tmp_local_device,tmp_local_letter = [],[]
tmp_mobile_device,tmp_mobile_letter = [],[]
tmp_local_number,tmp_mobile_number = 0,0
try:
part = psutil.disk_partitions()
except:
print("程序发生异常!!!")
box(None,"很抱歉,程序发生了异常","致命错误",0)
sys.exit(-1)
else:
#* 驱动器分类
for i in range(len(part)):
tmplist = part[i].opts.split(",")
if tmplist[1] == "fixed": #挂载选项数据内读到fixed = 本地设备
tmp_local_number = tmp_local_number + 1
tmp_local_letter.append(part[i].device[:2]) #得到盘符信息
tmp_local_device.append(part[i])
else:
tmp_mobile_number = tmp_mobile_number + 1
tmp_mobile_letter.append(part[i].device[:2])
tmp_mobile_device.append(part[i])
#*浅切片
local_device,local_letter = tmp_local_device[:],tmp_local_letter[:]
mobile_device,mobile_letter = tmp_mobile_device[:],tmp_mobile_letter[:]
local_number,mobile_number = tmp_local_number,tmp_mobile_number
return len(part) #返回当前驱动器数

5、定义一个打印函数(其目的是打印驱动器信息 参数为驱动器数量)
def print_device(n):
global local_device,local_letter,local_number,\
mobile_device,mobile_letter,mobile_number
print("=" * 50 + "\n读取到" + str(n) + "个驱动器")
for l in range(local_number):
print(local_letter[l],end="") #列出本地驱动器盘符
print("{" + local_device[0].opts + "}")
if(len(mobile_device)): #列出移动驱动器盘符
for m in range(mobile_number):
print(mobile_letter[m],end="")
print("{" + mobile_device[0].opts + "}")
else:
None
print("进程进入监听状态 " + "*" * 10)
return

6、主函数:
if __name__ == "__main__":
#*初次读取驱动器信息,打印驱动器详细
now_number = 0 #实时驱动数
before_number = updata() #更新数据之前的驱动数
print_device(before_number)
#进程进入循环 Loop Seconds = 1s
while True:
now_number = updata()
if(now_number > before_number):
print("检测到移动磁盘被插入...")
print_device(now_number)
box(None,"移动磁盘被插入\n","新插入磁盘",0)
before_number = now_number #刷新数据
elif(now_number < before_number):
print("检测到移动磁盘被拔出...")
print_device(now_number)
box(None,"移动磁盘被拔出\n","磁盘被拔出",0)
before_number = now_number
time.sleep(1)

7、运行结果如图?
怎么样?是不是很赞?学会没?点一波关注吧(*^__^*)


1、怎么关注?
在经验的右上角小编头像旁边点击关注,如图。

2、怎么点赞?
请在经验左侧点赞,如图。

3、怎么投票?
在经验的下方点击投票,如图。

4、如果觉得小编写的还不错,可以动动鼠标把它分享给您的朋友。
如何分享,鼠标移动到右下角第一个按钮上,在弹出的选项中进行分享,如图。
不尽感激。
