Что такое модуль Python glob? Для каких типов приложений Python его можно использовать?
Модуль Python glob используется для поиска путей, соответствующих определенному шаблону. Общий термин «glob» используется для описания методов сопоставления определенных шаблонов в соответствии с правилами оболочки Unix. С помощью glob вы также можете использовать подстановочные знаки («*,?, [диапазоны]) помимо точного поиска по строке, чтобы сделать поиск пути более эффективным.
Давайте изучим модуль Python glob!
Что такое модуль Python glob?
Модуль Python glob позволяет производить поиск по именам путей для поиска файлов, соответствующих заданному шаблону (который вы определяете). Правила, установленные оболочкой Unix, используются для определения предоставленного шаблона для сопоставления файлов.
Все пути к файлам, соответствующие определенному шаблону, возвращаются с помощью функции glob модуля glob. Мы можем использовать glob для поиска определенного шаблона файла или, что, возможно, более эффективно, мы можем использовать подстановочные знаки для поиска файлов, имена которых соответствуют заданному шаблону.
Чтобы использовать glob, нам нужно импортировать его с помощью оператора import Python, как показано ниже.
import glob
Примечание: glob — это встроенный модуль, который поставляется с Python, поэтому вам не нужно устанавливать его отдельно от вашей установки Python (например, с помощью pip или conda) перед импортом.
После импорта модуля glob мы можем использовать его для поиска файлов, соответствующих определенному шаблону на нашей локальной машине.
Следующий фрагмент кода сопоставляет определенное имя файла в каталоге /opt/app/tutorial/ и отображает его в выходных данных.
import glob
file = glob.glob("/opt/app/tutorial/file1.txt")
print(file)
Вывод:
['/opt/app/tutorial/file1.txt']
В приведенном выше коде мы ищем только один текстовый файл, мы также можем искать несколько файлов с одинаковым расширением.
import glob
files = glob.glob("/opt/app/tutorial/*.txt")
print(files)
Как вы видите, мы указали «*.txt», что соответствует всем файлам с расширением txt в указанном каталоге. Символ «*» является подстановочным знаком.
Предположим, что в каталоге /opt/app/tutorial/ у нас есть следующие пять текстовых файлов:
файл1.txt файл2.txt файл3.txt файл4.txt файл5.txt
После выполнения кода Python я получаю следующий вывод:
['/opt/app/tutorial/file2.txt', '/opt/app/tutorial/file3.txt', '/opt/app/tutorial/file1.txt', '/opt/app/tutorial/file4.txt', '/opt/app/tutorial/file5.txt']
Функция glob.glob()
возвращает список всех файлов, соответствующих указанному нами пути.
Вы также можете видеть, что…
Функция glob() модуля Python glob возвращает результаты в произвольном порядке.
Использование абсолютных и относительных путей с помощью Python glob
Путь, который мы указываем для функции glob(), может быть абсолютным или относительным.
Давайте посмотрим, что это значит…
- Абсолютный путь: это полный путь к файлу от корня файловой системы.
- Относительный путь: это путь относительно текущего каталога.
Два фрагмента кода, которые мы видели ранее, используют абсолютный путь.
Теперь давайте рассмотрим пример использования относительного пути…
import glob
files = glob.glob("*.txt")
print(files)
Путь, указанный в этом фрагменте кода, является относительным и относится к текущему каталогу.
Из вывода видно, что список файлов содержит только имена файлов, а не полный путь к каждому файлу:
['file2.txt', 'file3.txt', 'file1.txt', 'file4.txt', 'file5.txt']
Как использовать glob для рекурсивного поиска файлов
Слово рекурсивный означает повторение, которое относится к повторному применению правила. Мы также можем использовать glob для рекурсивного поиска файлов, что означает поиск файлов в подкаталогах.
Рекурсивная природа модуля glob полезна, поскольку вы можете не знать точное местоположение искомых файлов.
Чтобы включить рекурсивное поведение, необходимо передать рекурсивный логический аргумент в функцию glob()
, установленную в True. По умолчанию этот аргумент имеет значение False.
Прежде чем использовать рекурсивный аргумент, нам нужно понять поведение подстановочного знака «двойная звездочка» (**) при использовании с функцией glob.glob()
.
Создайте каталог с именем test_dir в текущем каталоге, а затем внутри test_dir создайте файл с именем file6.txt. Наша структура каталогов становится следующей:
файл1.txt файл2.txt файл3.txt файл4.txt файл5.txt test_dir/file6.txt
Теперь выполните предыдущий код Python, который использует «*.txt» как выражение имени пути. Вывод будет следующим:
['file2.txt', 'file3.txt', 'file1.txt', 'file4.txt', 'file5.txt']
Теперь передайте рекурсивный аргумент в функцию glob:
import glob
files = glob.glob("*.txt", recursive=True)
print(files)
При выполнении кода вы заметите, что вывод не меняется. Это потому, что рекурсивный аргумент должен использоваться вместе с подстановочным знаком двойной звездочки (**).
Обновите выражение, переданное функции glob()
, как показано ниже (не меняйте ничего в предыдущем коде):
files = glob.glob("**/*.txt", recursive=True)
На этот раз в выводе вы также увидите «test_dir/file6.txt». Наш код сопоставил файлы.txt в текущем каталоге, а также файл.txt в подкаталоге test_dir.
['file2.txt', 'file3.txt', 'file1.txt', 'file4.txt', 'file5.txt', 'test_dir/file6.txt']
Теперь попробуем установить recursive в значение False, не меняя выражение имени пути:
files = glob.glob("**/*.txt", recursive=False)
Вывод:
['test_dir/file6.txt']
Наш код сопоставил только файл в подкаталоге.
Теперь вы знаете, как работает двойная звездочка вместе с рекурсивным параметром при использовании функции glob()
.
Использование подстановочных знаков с glob
С модулем glob вы можете использовать подстановочные знаки. Существует много подстановочных знаков, но наиболее используемые подстановочные знаки описаны ниже.
Звездочка (*): glob использует звездочку (*), также известную как звездочка, для сопоставления нуля или более символов.
filepath = "*.txt"
filepath = "*.py"
filepath = "*.jpg"
В приведенных выше примерах * будет соответствовать всем файлам с указанным расширением.
Двойная звездочка (**): две звездочки (**) — то же самое, что и одна звездочка, но они работают с подпапками. Когда вы ищете рекурсивно, используйте двойную звездочку (**) для поиска файлов в текущих папках, а также в подпапках.
filepath = "docs/**/*.txt"
filepath = "python/**/*.py"
filepath = "images/**/*.jpg"
Квадратные скобки ([ ]): квадратные скобки являются очень мощным подстановочным символом, поскольку они позволяют искать файлы, используя различные комбинации символов.
Например:
- Допустим, вы хотите найти файлы, имена которых соответствуют строчным гласным буквам. Для этого вам нужно указать все строчные гласные буквы в квадратных скобках: [aeiou].
- [0-9]: Если вы хотите сопоставить любые цифры, укажите цифры от 0 до 9 в квадратных скобках.
- [AZ]: соответствует любым заглавным буквам, [az] соответствует любым строчным буквам. Вы также можете комбинировать заглавные и строчные буквы следующим образом: [az,AZ].
- Если вы хотите исключить определенные символы, то вы можете использовать квадратные скобки, а также указать символ (!). Например: [!abc].
Давайте рассмотрим несколько практических примеров, чтобы понять подстановочные знаки.
Мы уже видели ранее, как работают подстановочные знаки * и **. Теперь давайте рассмотрим пример с квадратными скобками ([ ]).
В квадратных скобках мы указываем последовательность цифр или букв для поиска:
import glob
path1 = "[a-e]*.txt"
print('Files with a name that starts with a letter between a and e in the current directory')
print(glob.glob(path1))
path2 = "[1-5]*.txt"
print('Files with a name that starts with a number between 1 and 5 in the current directory')
print(glob.glob(path2))
Создайте следующие файлы в текущем каталоге, чтобы убедиться, что подстановочные выражения работают так, как и ожидалось:
a.txt ask.txt cat.txt d.txt echo.txt delta.txt fox.txt 1.txt 134.txt 345.txt 67.txt
А теперь выполните код.
Вывод:
Files with a name that starts with a letter between a and e in the current directory
['echo.txt', 'ask.txt', 'a.txt', 'd.txt', 'delta.txt', 'cat.txt']
Files with a name that starts with a number between 1 and 5 in the current directory
['345.txt', '1.txt', '134.txt']
Наш код работает так, как и ожидалось, а файлы «fox.txt» и «67.txt» не совпадают.
Почему следует использовать iglob, а не glob в Python?
До сих пор мы использовали функцию glob()
. В модуле glob есть еще одна функция, называемая iglob()
.
Функция iglob()
похожа на функцию glob()
, главное отличие состоит в том, что iglob()
возвращает генератор, который выдает имена файлов, соответствующие заданному шаблону.
Давайте подтвердим тип объекта, возвращаемого функцией iglob()
, используя один из предыдущих примеров кода. Мы просто заменим функцию glob на функцию iglob.
import glob
files = glob.iglob("*.txt")
print(type(files))
[output]
<class 'generator'>
Функция glob() проходит по всем файлам и сохраняет их в памяти одновременно, в то время как iglob() возвращает генератор, который позволяет перебирать все файлы, не сохраняя их одновременно в памяти.
Передав генератор функции Python next(), вы получите обратно первое имя файла, возвращаемое функцией iglob:
print(next(files))
[output]
file2.txt
Функция iglob() очень полезна, когда мы сопоставляем большое количество файлов. Мы можем рисковать заполнить всю память, загружая их все с помощью glob().
Чтобы избежать этого, iglob() помогает нам сопоставить все имена файлов в виде генератора, что повышает производительность и сокращает использование памяти.
Чтобы вывести все файлы, соответствующие функции iglob, можно использовать цикл for в Python:
import glob
files = glob.iglob("*.txt")
for filename in files:
print(filename)
Заключение
Теперь у вас должно быть четкое понимание того, как работает модуль glob. Вы узнали, как модуль glob особенно полезен для задач, связанных с сопоставлением шаблонов имен файлов, и как получить список всех файлов, которые соответствуют определенному шаблону.
Мы рассмотрели несколько практических примеров того, как на самом деле работает модуль glob, включая некоторые из наиболее используемых подстановочных знаков.
Вы также увидели разницу между функциями glob()
и iglob()
и поняли, почему следует использовать iglob()
вместо функции glob()
.