2009-05-05 8 views

Odpowiedz

48
import win32api 

drives = win32api.GetLogicalDriveStrings() 
drives = drives.split('\000')[:-1] 
print drives 

Adaptacja: http://www.faqts.com/knowledge_base/view.phtml/aid/4670

+0

fantastyczne. Pracował idealnie. –

+0

Po prostu wypróbowałem to w wersji 2.6 i otrzymałem dodatkowy pusty ciąg na końcu. Nadal dobra odpowiedź. –

+0

@ Mark: edytuj, aby naprawić – Claudiu

50

Bez przy użyciu dowolnych zewnętrznych bibliotek, jeśli to ma znaczenie:

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 __name__ == '__main__': 
    print get_drives()  # On my PC, this prints ['A', 'C', 'D', 'F', 'H'] 
+0

Jakikolwiek powód, by nie używać string.lowercase lub string.ascii_lowercase zamiast string.letters [len (string.letters)/2:]? –

+0

@John: Bez powodu - dzięki za sugestię, teraz zmieniony na string.uppercase (ponieważ dla liter dysków preferuję czapki, nie wiem dlaczego 8-) – RichieHindle

+1

[c + ': \\' dla c w string.lowercase if os.path.isdir (c + ': \\')] –

6

Te wyglądają na lepsze odpowiedzi. Oto mój hackish cruft

import os, re 
re.findall(r"[A-Z]+:.*$",os.popen("mountvol /").read(),re.MULTILINE) 

riffy nieco na odpowiedź RichieHindle „s; to naprawdę nie jest lepsza, ale można dostać się do okna wykonywać pracę wymyślanie rzeczywistych liter alfabetu

>>> 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:\\'] 
+1

Podoba mi się to rozwiązanie. Dogodnie nie musi korzystać z Win32api. – WorldDominator

+0

Otrzymuję ten błąd podczas uruchamiania twojego kodu: –

+0

'UnicodeDecodeError: kodek 'charmap' nie może dekodować bajtu 0x81 na pozycji 586: mapowanie znaków na ' –

8

Microsoft Script Repository obejmuje this recipe które mogłyby pomóc. Nie mam komputera z systemem Windows, aby go przetestować, więc nie jestem pewien, czy chcesz "Nazwa", "Nazwa systemu", "Nazwa woluminu", czy może coś innego.

+1

Dziękujemy za połączenie z repozytorium Microsoft Script. –

+0

Zawsze czułem, że jest to doskonałe źródło informacji dla progerników systemu Windows, które nie jest powszechnie znane :-) –

+0

Kolejne +1 dla łącza do repozytorium Microsoft Script, o którym wcześniej nie słyszałem. –

0

Ponieważ nie mają Win32API zainstalowany na moim polu notebooków Użyłem tego rozwiązania za pomocą 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 

alternatywnie można uzyskać różnicę zarówno liście, jak to prostsze rozwiązanie (po uruchomieniu wmic podproces jako mount_letters):

#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 

oba rozwiązania są podobne szybko, ale domyślam się, że set set jest lepszy z jakiegoś powodu, prawda?

0

W ramach podobnego zadania musiałem również pobrać darmowy list motywacyjny. Zdecydowałem, że chcę najwyższego dostępnego listu. Najpierw napisałem to bardziej idiomatycznie, a potem chrupnąłem do 1-linijki, żeby sprawdzić, czy to ma sens. Niesamowite, jak rozumowanie listowe, uwielbiam zestawy do tego: unused=set(alphabet)-set(used) zamiast robić unused = [a for a in aphabet if a not in used]. Fajne rzeczy!

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 

Jedna wkładka:

def get_drive(): 
    highest = sorted(list(set(map(chr, range(ord('A'), ord('Z')+1))) - 
          set(win32api.GetLogicalDriveStrings().split(':\\\000')[:-1])))[-1] 

Wybrałem również alfabetu, używając mapy/zakres/ord/chr nad użyciem ciąg od części łańcucha są przestarzałe.

4

Znaleziono to rozwiązanie w Google, nieznacznie zmodyfikowane w stosunku do oryginału.Wydają się dość pythonic i nie potrzebuje żadnych „egzotyczne” import

import os, string 
available_drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)] 
+0

FWIW to mi się nie udało co najmniej raz z nieznanego powodu – NirIzr

2

Napisałem ten kawałek kodu:

import os 
drives = [ chr(x) + ":" for x in range(65,90) if os.path.exists(chr(x) + ":") ] 

Jest on oparty na @ odpowiedź barmaley, ale ma tę zaletę, że nie stosując string moduł, na wypadek gdybyś nie chciał z niego korzystać. Działa również na moim systemie, w przeciwieństwie do odpowiedzi @ SingleNegationElimination.

1

Więcej optymalne rozwiązanie oparte na @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 
1

Oto moje podejście wyższa wydajność (prawdopodobnie może być wyższa):

>>> 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'] 

Nikt tak naprawdę nie używa Pythona performatywny featurability ...

Tak, nie podążam za standardowymi konwencjami ścieżki Windows ('\\') ...
We wszystkich moich latach używania Pythona, miałem nie ma problemów z "/" ścieżkami w dowolnym miejscu i uczyniłem je standardowymi w moich programach.

2

W systemie Windows można zrobić os.popen

import os 
print os.popen("fsutil fsinfo drives").readlines() 
+0

Rozwiązanie tylko dla administratorów – pstatix

Powiązane problemy