Учимся работать с внешними файлами.
В этой главе мы научимся активно взаимодействовать с окружающим миром, а именно, мы узнаем, как читать, создавать, удалять, копировать, переименовывать, изменять, архивировать файлы, в этом деле нам помогут стандартные модули os, shutil, csv и zipfile. Это тема из стандартного учебника, посему пройдемся по ней галопом, за подробностями, опять же, можно идти в широкодоступные ресурсы.
Первым шагом будет поиск папок и файлов, сделаем мы это с помощью метода os.listdir:
import os
sysdir = ‘c:/’
print(os.listdir(sysdir))
Получили все папки и файлы в системном каталоге:
['$360Section', '$Recycle.Bin', 'AdwCleaner', 'AMTAG.BIN', 'Config.Msi', 'Documents and Settings', 'hiberfil.sys', 'MSOCache', 'pagefile.sys', 'PerfLogs', 'Port Progs', 'Program Files', 'Program Files (x86)', 'ProgramData', 'Python2710', 'Python34', 'Python340', 'Recovery', 'swapfile.sys', 'System Volume Information', 'Telegram Desktop', 'Users', 'Windows']
Попробуем разделить файлы и папки, для это воспользуемся функциями из модуля os и напишем следующую небольшую программу:
import os # импорт модуля
dirp = 'c:/' # путь к папке
files = [] # создание пустого списка для файлов
dirs = [] # создание пустого списка для папок
for i in os.listdir(dirp): # проходим циклом по всем элементам в папке
if os.path.isfile(dirp + '/' + i): # проверка файлов
files.append(i) #запись файлов в список
elif os.path.isdir(dirp + '/' + i): # проверка папок
dirs.append(i) # запись папок в список
print(files, dirs) # вывод списков на печать
Мы получили два списка с файлами и с папками. Разберем работу программы, каждый этап имеет описание, но этого недостаточно. Появился очень важный оператор append – он служит для внесения в списки новых элементов, причем элементы добавляются в конец списка, появилась интересная запись (dirp + '/' + i) – это сложение строк, работает как для чисел, мало того, строки можно умножать на числа. В данном случае мы складываем название папки, слэш и имя элемента, чтобы получить полный путь. Сделаем в консоли Питон небольшой опыт по сложению и умножению строк:
>>> x = 'слово'
>>> x+x
'словослово'
>>> x*3
'словословослово'
Другие арифметические операции для строк не применимы. Давайте теперь попробуем получить файлы с определенным расширением. Для этого, также, существуют специальные методы, но мы воспользуемся наиболее простым и надежным способом. Нередко у файлов бывает больше одной точки в названии, например pip-18.1.tar.gz, в нашем распоряжении есть метод split, который разбивает текст по заданному символу. Проверим в консоли как, он работает:
>>> filename = 'pip-18.1.tar.gz'
>>> filename.split('.')
['pip-18', '1', 'tar', 'gz']
В качестве разделителя мы выбрали точку, соответственно название файла по трем точкам разбилось на четыре части, из которых последняя часть является искомым расширением файла. Мы уже научились извлекать по индексу элементы из списка, но нам нужен последний элемент и мы не знаем, на сколько частей будет разбиваться имя файла. У Питона на этот случай есть чудесный инструмент – элементы списков можно отсчитывать от конца, начиная от -1, последний элемент будет иметь индекс [-1], предпоследний - [-2], и т. д.
>>> filename.split('.')[-1]
'gz'
Теперь мы сможем находить на компьютере файлы с определенным расширением. Напишем следующий небольшой код:
import os
dirp = 'd:/books/Python'
files = []
for i in os.listdir(dirp):
if os.path.isfile(dirp + '/' + i) and i.split('.')[-1] == 'pdf':
files.append(i)
print(files)
['AByteofPythonRussian-2.0.pdf', 'allpy.pdf', 'byte-of-python.pdf']
Мы получили из заданной папки все файлы с расширением .pdf, для чего мы несколько переделали прежний код, избавились от проверки папок, в проверку файла с помощью оператора and добавили дополнительное условие. Теперь научимся создавать папки и копировать файлы, после чего сможем написать полезную программу и перейдем к другой теме. Создаются папки различными способами, мы воспользуемся самым простым os.mkdir, однако способ ограничен созданием одноуровневых папок, для создания вложенных папок используется метод os.makedirs. Напишем программу, которая будет создавать папку, копировать в нее с переименованием файлы из другой папки и создавать текстовый файл со списком файлов. Нам потребуется модуль shutil. Продолжаем программировать:
import os, shutil, zipfile
dirp = 'd:/books/Python' #папка с файлами
path = 'd:/py_book' #создаваемая папка
files = []
new_files = []
for i in os.listdir(dirp):
if os.path.isfile(dirp + '/' + i) and i.split('.')[-1] == 'pdf':
files.append(dirp + '/' + i)
new_files.append(path + '/new_' + i)
# мы доработали предыдущий код: через запятую импортированы еще два модуля, в папку files вносится полный путь файлов, в папку new_files вносится новый путь файлов. Идем дальше.
try:
os.mkdir(path)
except:
print ("Создать директорию %s не удалось" % path)
else:
print ("Успешно создана директория %s" % path)
#в этой части программы мы создали папку, но не просто, а с проверкой, для чего применили конструкцию с try, она нужна для того, чтобы Питон пытался произвести действие, в случае неудачи(например, если такая папка уже существует) выдается исключение с сообщением, что папку создать не удалось, в случае успеха – противоположное сообщение. Еще в коде появилась интересная конструкция с символом процентов: "Успешно создана директория %s" % path, она позволяет внедрять в строку элементы извне, при чем это может быть не только строка, но и число. Теперь попробуем создать текстовый файл со списком файлов. Питон позволяет делать это без привлечения каких-либо модулей:
f = open(path + ‘/file_list.txt’, ‘w’)
for i in new_files:
f.writelines(i + ‘\n’)
f.close()
Функция open открывает файл на запись, за что отвечает параметр ‘w’, если такого файла нет, то создается новый(о других значения параметра можно посмотреть справку). Далее цикл перебирает список с новыми названиями, а соответствующий метод построчно записывает их в файл, в конце ставится символ перехода на новую строку. После всего этого текстовый файл закрывается.
Теперь можем копировать, делается это тоже легко:
for i,j in zip(files, new_files):
shutil.copyfile(i,j)
У нас копирование уместилось в один цикл, но цикл не простой, функция zip позволила нам сразу пройтись по двум спискам, поскольку объединяет в кортежи элементы из последовательностей, переданных в качестве аргументов. Посмотрим ее работу в консоли:
>>> list(zip([1,2,3],[3,3,3]))
[(1, 3), (2, 3), (3, 3)]
Списков может быть и больше двух. Далее сработал метод из нового модуля shutil.copyfile(i,j) – первым аргументом подается старое название файла, вторым – новое.
Теперь научимся архивировать файлы, это опять легко:
zname = path + '/myzip.zip' #создаем переменную - название и местоположение файла
newzip = zipfile.ZipFile(zname,'w') #создаем архив
for i in new_files: #добавляем файлы в архив
newzip.write(i)
newzip.close() #закрываем архив
Создание архива мало чем отличается от создания текстового файла. Можем посмотреть нашу новую папку:

Мы научились работать с файловой системой, создавать текстовые файлы и архивы. Эти знания будут всегда востребованы.
Осталась не раскрытой, из озвученных, тема csv, заполним пробел. Многие из вас наверняка знакомы с этим форматом файлов, он широко используется для хранения и обмена информацией, в том числе инженерами. Структура файла простая – это двумерный массив, состоящий из строк, элементы в строках разделены сепараторами, обычно это пробел. В дальнейшем мы научимся взаимодействовать с MS Exsel, но это будет гораздо сложней. Во многих случаях csv решит наши задачи. Модуль для работы с этим форматом принадлежит к числу встроенных, а принципы записи и чтения мало чем отличаются от работы с обычным текстовым форматом. Файл для примера можем скачать с сайта https://rp5.ru/Архив_погоды_в_Москве_(ВДНХ)...
Ближе к концу книги мы с вами узнаем, как построить систему автоматического бэкапа данных, но нам еще не хватает знаний и мы опять за ними пойдем, в этот раз, наверное, поход будет самым увлекательным – мы научимся находить и устанавливать дополнительные модули Питон.
Красава! Каждый день начинаю и заканчиваю тем, чтобы проверить, не появились ли от тебя еще статьи! Продолжай в том же духе!
ОтветитьУдалитьНу как же после таких слов не продолжать писать? Спасибо на добром слове. Рад что кому то это настолько интересно. Буду стараться.
Удалить