Командная строкаКурсы

Ищем самый большой файл на компьютере с Python.

Опубликовано

ссылка на репл если окно ниже не работает

На предыдущем уроке мы написали функцию, которая «прогуливается» по указанной директории и выводит на экран наименования всех файлов, которые она нашла. Давайте немного модифицируем нашу функцию.
Во-первых, переименуем её в find_big_file(dir). Изменения должны коснуться трёх строк.
Во-вторых, вместо того чтобы переписывать переменную name, объявим отдельную переменную abs_name, которая будет хранить абсолютный путь.
Во-третьих, давайте рядом с именем будем выводить размер файла. В этом нам поможет функция getsize() из модуля path библиотеки os.

Все изменения подчёркнуты

Не всегда результат может быть ожидаемым

А дальше дело за малым. Нужно просто сравнить все значения и найти наибольшее. Объявим переменную max_size=0 и name_big_file= ‘ ‘ . Будем обновлять значения переменных, если нашёлся файл больший чем текущий. И в конце после выхода из цикла, просто выведем информацию на экран.

Но код работает на так, как мы ожидали. Мало того что он не ищет большой файл, он ещё и выводит вместо одной строчки несколько. Почему? Мы ведь использовали функцию print() за пределам цикла, после его окончания работы. Всё дело в рекурсии! print() действительно находится за пределами цикла, но сколько раз функция find_big_file() вызывает саму себя, столько раз мы увидим строчку с именем и размером файла. Более того, переменные max_size и name_big_file обнуляются при каждом вызове функции, поэтому мы получаем такой хаос. Рекомендую набрать код данной функции и, прежде чем продолжить, попробовать решить эту проблему.

True story

А что если при каждом вызове функции показатели размера самого большого файла и его имени, не сбрасывались бы, а сохранялись и передавались между функциями. Таким образом, на каком бы уровне рекурсии мы сейчас не находились, у нас всегда бы была актуальная информация о том, какой файл сейчас самый большой.

В данной ситуации нас спасёт ссылочная модель хранения данных. При передаче параметров в функцию, некоторые из них передаются по значению, а некоторые по ссылке. Это зависит от типа данных передаваемых в аргументе. У чисел и строк предаётся значение (иными словами копия данных), а у списков и словарей передаётся ссылка (иными словами указатель на область оперативной памяти где хранится список или словарь).

Из-за ссылочной передачи значения, если мы поменяем такой объект внутри функции, то он у нас изменится и за её пределами. Вот такие вот фокусы! Не переживайте, если вы не совсем понимаете как работает передача параметра по значению или по ссылке, это очень большая и отдельная тема. Главное что стоит подчеркнуть — если мы передаём ссылочный аргумент, то мы работаем не с копией, а с оригиналом.

Пишем код.

Перед вызовом функции объявим словарь big_file, который хранит информацию о имени и размере самого большого файла. Именно этот словарь будет изменяться внутри функции find_big_file() . Передадим его вторым параметром. А после мы просто распечатаем big_file.

Далее, объявим ещё один параметр file_info, в нём будет храниться наш словарь. Изменим условие где мы сравниваем размер текущего файла с размером большого файла. И внутри условия будем обращаться по ключам к нашему словарю и менять их значения, если нашёлся файл большего размера, чем указан в словаре.

А на этом всё! Можно переходить к подведению итогов.