Plus ou moins ce qui est écrit sur le panneau: existe-t-il un moyen (simple) de lister toutes les lettres de lecteur actuellement utilisées dans un système Windows?
(Mon google-fu semble m'avoir laissé tomber sur celui-ci.)
En relation:
import win32api
drives = win32api.GetLogicalDriveStrings()
drives = drives.split('\000')[:-1]
print drives
Adapté de: http://www.faqts.com/knowledge_base/view.phtml/aid/4670
Sans utiliser de bibliothèques externes, si cela vous tient à cœur:
import string
from ctypes import windll
def get_drives():
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
return drives
if __== '__main__':
print get_drives() # On my PC, this prints ['A', 'C', 'D', 'F', 'H']
Celles-ci ressemblent à de meilleures réponses. Voici mon crétin hack
import os, re
re.findall(r"[A-Z]+:.*$",os.popen("mountvol /").read(),re.MULTILINE)
Riffing un peu sur RichieHindle réponse de /; ce n'est pas vraiment mieux, mais vous pouvez avoir Windows pour faire le travail de trouver de vraies lettres de l'alphabet
>>> import ctypes
>>> buff_size = ctypes.windll.kernel32.GetLogicalDriveStringsW(0,None)
>>> buff = ctypes.create_string_buffer(buff_size*2)
>>> ctypes.windll.kernel32.GetLogicalDriveStringsW(buff_size,buff)
8
>>> filter(None, buff.raw.decode('utf-16-le').split(u'\0'))
[u'C:\\', u'D:\\']
Le Microsoft Script Repository inclut cette recette qui pourrait vous aider. Cependant, je n'ai pas de machine Windows pour le tester, donc je ne suis pas sûr de vouloir "Nom", "Nom du système", "Nom du volume" ou peut-être autre chose.
Trouvé cette solution sur Google, légèrement modifiée par rapport à l'original. Semble jolie Pythonic et n'a pas besoin d'importations "exotiques"
import os, string
available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)]
Solution plus optimale basée sur @RichieHindle
def get_drives():
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
letter = ord('A')
while bitmask > 0:
if bitmask & 1:
drives.append(chr(letter) + ':\\')
bitmask >>= 1
letter += 1
return drives
J'ai écrit ce morceau de code:
import os
drives = [ chr(x) + ":" for x in range(65,90) if os.path.exists(chr(x) + ":") ]
Il est basé sur la réponse de @ Barmaley, mais présente l'avantage de ne pas utiliser le module string
Au cas où vous ne voudriez pas l'utiliser. Cela fonctionne également sur mon système, contrairement à la réponse de @ SingleNegationElimination.
Sous Windows, vous pouvez faire un os.popen
import os
print os.popen("fsutil fsinfo drives").readlines()
Voici mon approche plus performante (pourrait probablement être plus élevée):
>>> from string import ascii_uppercase
>>> reverse_alphabet = ascii_uppercase[::-1]
>>> from ctypes import windll # Windows only
>>> GLD = windll.kernel32.GetLogicalDisk
>>> drives = ['%s:/'%reverse_alphabet[i] for i,v in enumerate(bin(GLD())[2:]) if v=='1']
Personne n'utilise vraiment la fonctionnalité performative de python ...
Oui, je ne suis pas les conventions de chemin standard Windows ('\\') ...
Au cours de toutes mes années d’utilisation de python, je n’ai rencontré aucun problème avec "/" où que des chemins soient utilisés et l’ai standardisé dans mes programmes.
Voici une autre excellente solution si vous souhaitez répertorier uniquement les lecteurs de votre disque et non les lecteurs réseau mappés. Si vous voulez filtrer par différents attributs, imprimez simplement les drps.
import psutil
drps = psutil.disk_partitions()
drives = [dp.device for dp in drps if dp.fstype == 'NTFS']
Dans le cadre d'une tâche similaire, j'avais également besoin d'une lettre de lecteur gratuite. J'ai décidé que je voulais la plus haute lettre disponible. Je l’écrivis d’abord de façon plus idiomatique, puis je l’écrivis sur une ligne pour voir si cela avait encore un sens. Aussi géniaux que soient les compréhensions de liste, j'adore les ensembles pour ceci: unused=set(alphabet)-set(used)
au lieu de devoir faire unused = [a for a in aphabet if a not in used]
. Truc cool!
def get_used_drive_letters():
drives = win32api.GetLogicalDriveStrings()
drives = drives.split('\000')[:-1]
letters = [d[0] for d in drives]
return letters
def get_unused_drive_letters():
alphabet = map(chr, range(ord('A'), ord('Z')+1))
used = get_used_drive_letters()
unused = list(set(alphabet)-set(used))
return unused
def get_highest_unused_drive_letter():
unused = get_unused_drive_letters()
highest = list(reversed(sorted(unused)))[0]
return highest
La doublure:
def get_drive():
highest = sorted(list(set(map(chr, range(ord('A'), ord('Z')+1))) -
set(win32api.GetLogicalDriveStrings().split(':\\\000')[:-1])))[-1]
J'ai aussi choisi l'alphabet en utilisant map/range/ord/chr sur en utilisant string car certaines parties de string sont déconseillées.
Comme je n’ai pas installé win32api sur mon parc de cahiers, j’utilisais cette solution avec wmic:
import subprocess
import string
#define alphabet
alphabet = []
for i in string.ascii_uppercase:
alphabet.append(i + ':')
#get letters that are mounted somewhere
mounted_letters = subprocess.Popen("wmic logicaldisk get name", Shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#erase mounted letters from alphabet in nested loop
for line in mounted_letters.stdout.readlines():
if "Name" in line:
continue
for letter in alphabet:
if letter in line:
print 'Deleting letter %s from free alphabet %s' % letter
alphabet.pop(alphabet.index(letter))
print alphabet
alternativement, vous pouvez obtenir la différence entre les deux listes de la manière suivante:
#get output to list
mounted_letters_list = []
for line in mounted_letters.stdout.readlines():
if "Name" in line:
continue
mounted_letters_list.append(line.strip())
rest = list(set(alphabet) - set(mounted_letters_list))
rest.sort()
print rest
les deux solutions sont similaires rapidement, mais je suppose que la liste est mieux pour une raison quelconque, non?
si vous ne souhaitez pas vous soucier des problèmes multi-plateformes, y compris ceux des plates-formes python telles que Pypy, et que vous souhaitiez utiliser un outil assez performant lorsque les lecteurs sont mis à jour pendant l'exécution:
>>> from os.path import exists
>>> from sys import platform
>>> drives = ''.join( l for l in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if exists('%s:/'%l) ) if platform=='win32' else ''
>>> drives
'CZ'
voici mon test de performance de ce code:
4000 iterations; threshold of min + 250ns:
__________________________________________________________________________________________________________code___|_______min______|_______max______|_______avg______|_efficiency
⡇⠀⠀⢀⠀⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣷⣷⣶⣼⣶⣴⣴⣤⣤⣧⣤⣤⣠⣠⣤⣤⣶⣤⣤⣄⣠⣦⣤⣠⣤⣤⣤⣤⣄⣠⣤⣠⣤⣤⣠⣤⣤⣤⣤⣤⣤⣄⣤⣤⣄⣤⣄⣤⣠⣀⣀⣤⣄⣤⢀⣀⢀⣠⣠⣀⣀⣤⣀⣠
drives = ''.join( l for l in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' if exists('%s:/'%l) ) if platform=='win32' else '' | 290.049ns | 1975.975ns | 349.911ns | 82.892%