Поиск Python для неизвестного расширения файла

Новичок в python, извините, если это простой вопрос. Я немного поискал и нашел много при поиске файлов с неизвестным именем и известным расширением файла, но не с известным именем и неизвестным расширением, и если никто не возражает, мне может понадобиться небольшая помощь, чтобы мой код работал правильно.

Я пытаюсь написать функцию Python, которая принимает каталог и имя, а затем возвращает список с путем ко всем файлам (с любым расширением файла) и каталогам с этим именем. Параметр каталога будет представлять собой диск компьютера (например, C или F), а параметр имени — это имя (без расширения) искомого файла.

Ниже приведен код, который у меня есть:

import os
import glob
def search_directory(directory,name):
    result = []
    for root,dirs,files in os.walk(directory,topdown=True):
        files_lower = []
        dirs_lower = []
        for i in files:
            files_lower.append(i.lower())
        for i in dirs:
            dirs_lower.append(i.lower())
        for i in glob.glob(name + '.*'):
            if i.lower() in files_lower:
                result.append(root + "\\" + files[files_lower.index(i.lower())])
        if name.lower() in dirs_lower:
            result.append(root + "\\" + dirs[dirs_lower.index(name.lower())])
    if (len(result) == 0):
        result.append("fileNotFound")
    return result

В настоящее время я могу найти результаты только в том случае, если копия файла находится в каталоге моей программы. Если там нет копии, он не находит файл, хотя на моем диске есть две копии.

Я надеялся, что кто-нибудь может объяснить мне, почему это так и как это исправить, чтобы он всегда находил файлы, которые я ищу.


person tvr2006    schedule 29.06.2016    source источник


Ответы (1)


Почему вы перезагружаетесь для поиска? Это означает, что вы в конечном итоге повторно сканируете каталоги, когда os.walk дает вам имена, поэтому вы можете просто проверить их напрямую, используя os.path.splitext для разделения расширения. Вы также можете упростить логику, сделав ее функцией генератора, чтобы вы выдавали файлы по мере их нахождения, быстрее получая результаты и избегая ненужного состояния, когда вы обрабатываете каждое имя файла и отбрасываете его:

def search_directory(directory,name):
    name = name.lower()  # Convert up front in case it's pass mixed case
    for root, dirs, files in os.walk(directory,topdown=True):
        for e in files + dirs:
            if os.path.splitext(e)[0].lower() == name:
                yield os.path.join(root, e)

Это делает его генератором (если вам нужен список, вы должны обернуть вызов в конструкторе list, чтобы реализовать генератор), поэтому он не сообщает вам, не было ли попаданий, но вызывающая функция (или функция-оболочка, которая преобразуется в list) могут определить это сами. Если вам нужно, простое логическое значение, инициализированное значением False, которое устанавливается в значение True перед yielding, может позволить вам выполнить ту же проверку, хотя обычно служебной функции не нужно беспокоиться о таких вещах.

person ShadowRanger    schedule 29.06.2016
comment
Чтобы было ясно, причина, по которой у вашего кода были проблемы, заключается в том, что glob.glob(name + '.*') всегда повторно ищет корневой каталог, потому что вы не добавили каталог, в который вы вошли. Но в любом случае это глупый дизайн, поэтому мой ответ полностью игнорирует проблему. - person ShadowRanger; 29.06.2016
comment
Спасибо! Я ценю помощь! Я не думал об отделении расширения, хотя, оглядываясь назад, это намного проще. И я довольно новичок в программировании, поэтому я не знал о генераторах или сопрограммах, поэтому я тоже ценю это. Еще одно дополнение к моему инструментарию :) - person tvr2006; 01.07.2016