在Python中,如何检查驱动器是否存在,而不会抛出可移动驱动器的错误?

以下是我到目前为止:

import os.path as op for d in map(chr, range(98, 123)): #drives bz if not op.isdir(d + ':/'): continue 

问题是它在Windows中popup“No Disk”错误框:

maya.exe – 没有磁盘:驱动器中没有磁盘。 请将磁盘插入驱动器\ Device \ Harddisk1 \ DR1 [取消,重试,继续]

我无法捕捉到exception,因为它实际上并没有抛出Python错误。

显然,这只发生在可移动的驱动器上有一个字母分配,但没有插入驱动器。

有没有办法解决这个问题,而没有具体告诉脚本哪个驱动器跳过?

在我的情况下,我在学校实验室的驱动器号改变取决于我在哪台实验室电脑。 另外,我没有安全权限来访问磁盘pipe理。

使用ctypes包来访问GetLogicalDrives函数。 这不需要像pywin32这样的外部库,所以它是可移植的,虽然它的工作有点笨拙。 例如:

 import ctypes import itertools import os import string import platform def get_available_drives(): if 'Windows' not in platform.system(): return [] drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives() return list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1]))) 

itertools.compress是在Python 2.7和3.1中添加的; 如果你需要支持<2.7或<3.1,那么这个函数的实现:

 def compress(data, selectors): for d, s in zip(data, selectors): if s: yield d 

如果你有win32file模块,你可以调用GetLogicalDrives() :

 def does_drive_exist(letter): import win32file return (win32file.GetLogicalDrives() >> (ord(letter.upper()) - 65) & 1) != 0 

要禁用错误弹出窗口,您需要使用pywin设置SEM_FAILCRITICALERRORS Windows错误标志:

 old_mode = win32api.SetErrorMode(0) SEM_FAILCRITICALERRORS = 1 # not provided by PyWin, last I checked win32api.SetErrorMode(old_mode & 1) 

这告诉Win32不要显示重试对话框; 当发生错误时,它立即返回到应用程序。

请注意,这是Python调用应该做的事情。 原则上,Python应该为你设置这个标志。 不幸的是,由于Python可能被嵌入到另一个程序中,所以它不能像这样改变进程范围内的标志,而且Win32没有办法以只影响Python而不是其他代码的方式来指定这个标志。

在Windows和Linux上,这两种方法都适用于Python 2和Python 3:

 import platform,os def hasdrive(letter): return "Windows" in platform.system() and os.system("vol %s: 2>nul>nul" % (letter)) == 0 

只要有一点解析是可以接受的,这是一个不需要安装win32api,也不需要遍历所有可能的驱动器盘符的方法。

 from subprocess import check_output def getDriveLetters(): args = [ 'wmic', 'logicaldisk', 'get', 'caption,description,providername', '/format:csv' ] output = check_output(args) results = list() for line in output.split('\n'): if line: lineSplit = line.split(',') if len(lineSplit) == 4 and lineSplit[1][1] == ':': results.append(lineSplit[1][0]) return results 

您还可以解析特定的驱动器类型,例如“网络连接”,通过添加and lineSplit[2] == 'Network Connection' “网络连接”来获取所有网络安装驱动器号的列表。

或者,不是返回一个列表,而是返回一个字典,其中键是驱动器号,值是unc路径( lineSplit[3] )。 或者其他任何你想从wmic 。 要查看更多选项: wmic logicaldisk get /?