Есть ли способ перечислить все доступные буквы дисков в Python? - PullRequest
40 голосов
/ 06 мая 2009

Более или менее то, что написано на банке: есть ли (простой) способ перечислить все используемые в настоящий момент буквы дисков в системе Windows?

(Кажется, мой гугл-фу подвел меня к этому.)

Связанный:

Ответы [ 14 ]

1 голос
/ 28 ноября 2016

Вот мой более высокопроизводительный подход (возможно, может быть и выше):

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

Никто действительно не использует перформативную способность Python ...

Да, я не следую стандартным соглашениям пути Windows ('\\') ...
За все мои годы использования python у меня не было проблем с '/' везде, где используются пути, и я сделал это стандартным в моих программах.

0 голосов
/ 11 марта 2018

, если вы не хотите беспокоиться о кроссплатформенных проблемах, в том числе на платформах Python, таких как Pypy, и хотите использовать что-то прилично производительное при обновлении дисков во время выполнения:

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

вот мой тест производительности этого кода:

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%
0 голосов
/ 09 сентября 2014

В рамках аналогичной задачи мне также нужно было получить букву свободного диска. Я решил, что хочу самое высокое доступное письмо. Сначала я выписал это более идиоматически, а затем сжал до 1 строки, чтобы увидеть, все ли это имеет смысл. Так же, как и списки, я люблю наборы для этого: unused=set(alphabet)-set(used) вместо того, чтобы делать unused = [a for a in aphabet if a not in used]. Классные вещи!

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

Один лайнер:

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

Я также выбрал алфавит, используя map / range / ord / chr, вместо строки, так как части строки устарели.

0 голосов
/ 02 мая 2014

Поскольку на моем ноутбуке не установлено ПО win32api, я использовал это решение с помощью 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

в качестве альтернативы вы можете получить разницу из обоих списков, как это более простое решение (после запуска подпрограммы wmic в виде 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

оба решения одинаково быстры, но я думаю, что сет-лист лучше по какой-то причине, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...