#!/usr/bin/env python # coding: utf-8 # # Программирование для дата-журналистики # # # ## Конспект лекции о работе с файлами и путями к ним # # - Лекция: И. Щуров # - Текст: А. Щёнников # - [Страница курса](http://math-info.hse.ru/s18/k) # # # # Мы будем работать с функциями для работы с операционной системой, для этого нам нужно импортировать модуль **os**. # In[1]: import os # Функция `getcwd()` (get current work directory) — возвращает *абсолютный* путь к текущей рабочей директории/каталогу/папке. Это далеко не обязательно та директория в которой находится запущенный .ipynb файл. # В зависимости от операционной системы путь может выглядеть по-разному: # # "/disk/user/dir" — под Mac/Linux # "D:\\user\\dir" — под Windows (в целом, современные версии понимают написание не через обратный слеш) # In[ ]: os.getcwd() # Так, например, если в текущем рабочем каталоге будет находиться файл "myfile.txt", то мы сможем открыть его указав лишь его имя. # Но абсолютный путь к файлу будет выглядеть как: # # "/disk/user/dir/myfile.txt" # или # "D:\\disk\user\dir\myfile.txt" # In[3]: with open("myfile.txt") as f: print(f.read()) # Обратите внимание, что если вы хотите вручную прописать путь к файлу, а не только его имя, чтобы использовать в строке символ обратного слеша вам нужно написать его дважды _**"\\\\"**_, т.к. сам по себе знак _**"\\"**_ имеет особый смысл (например, используется для передачи специальных символов типа `\n`) # In[4]: print("a\\b") # ### Задача # In[ ]: # Создайте любой файл в текущем рабочем каталоге # Откройте его, используя абсолютный путь, как в примере внизу # In[6]: with open("/Users/teacher/myfile.txt") as f: print(f.read()) # In[7]: with open("/Users/teacher/My Nice Folder/myfile.txt") as f: print(f.read()) # In[8]: with open("My Nice Folder/myfile.txt") as f: print(f.read()) # Текущий рабочий каталог можно поменять, используя функцию **os.chdir()**. Ваш .ipynb файл при этом останется на прежнем месте, измениться лишь точка отсчета для доступа к файлам. # In[13]: os.chdir('/Users/teacher') # In[14]: os.chdir("My Nice Folder") # In[15]: os.getcwd() # Будьте внимательны, при смене рабочего каталога вы не сможете открывать только по имени файлы, которые лежали в прежнем рабочем каталоге. # In[16]: with open("myfile.txt") as f: print(f.read()) # In[17]: with open("/Users/teacher/myfile.txt") as f: print(f.read()) # Так же как и с файлами, если вам необходимо обратиться к каталогу, который лежит в текущем рабочем каталоге, вам достаточно просто написать его имя. Если же вы хотите обратиться к каталогу, *в котором* находится ваш текущий рабочий каталог, досаточно написать _**".."**_. # # Например, наша файловая система выглядит следующим образом: # # disk/user/dir0/dir1/dir2 # # Текущий рабочий каталог — **dir1**, нам необходимо обратиться к каталогу **dir2**, тогда достаточно написать _**"dir2/"**_. Если мы хотим попасть в каталог **dir0**, нужно написать _**"../"**_ # In[18]: with open("../myfile.txt") as f: print(f.read()) # Путь, который строится относительно текущего рабочего каталога, называется _относительным_ путём. # Путь _**"./"**_ (одна точка) — это способ указать текущий рабочий каталог в виде строки. # In[20]: with open("./myfile.txt") as f: print(f.read()) # In[21]: os.chdir("/Users/teacher") # Метод **os.listdir()** возвращает список всех объектов (и файлов и каталогов), которые содердатся в директории. В скобках можно указать путь к директории (в виде строки, например, `os.listdir("disk/user/dir0/dir1/dir2")`) список объектов которой необходимо получить, по умолчанию функция возвращает список объектов текущего рабочего каталога. # In[25]: os.listdir() # In[26]: os.listdir("My Nice Folder/") # Файл в каталоге не всегда может иметь в конце названия привычное расширение в виде несколькоих знаков после точки (.txt/.csv). Чтобы определить является ли объект каталога файлом, а не каталогом, существует функция **os.path.isfile()**, которая на вход принимает путь к файлу в виде строки. # In[27]: os.path.isfile("results.csv") # In[30]: os.path.isfile("My Nice Folder") # Соответственно с помощью функции **os.path.isdir** можно проверить является ли объект директорией. # In[31]: os.path.isdir("My Nice Folder") # In[34]: # Задача: вывести на экран все файлы в текущем каталоге (без подкаталогов) for filename in os.listdir(): if os.path.isfile(filename): print(filename) # По сути, как было указано выше, пути к файлам это обычные строки, и с ними можно производить обычные операции предусмотренные для строк. Например, если у нас в текущем рабочем каталоге есть каталог `"dir2"`, а в нем лежит файл _`"file.txt"` и мы работаем под Windows, то мы можем построить относительный путь к этому файлу так: `"dir2" + "\\" + "file.txt"`, и получим строку `"dir2\\file.txt"`. Но гораздо аккуратнее будет соединять отдельные части пути с помощью функции `os.path.join()`, которая на вход получает два или больше компонента пути и создаёт строку в том формате, который поддерживается операционной системой, на которой запущен код. # In[35]: folder = "My Nice Folder" filename = "myfile.txt" # In[36]: # хочу сконструировать путь к файлу с именем, лежащем в filename, # внутри каталога, с именем, лежащим в folder # In[38]: with open(os.path.join(folder, filename)) as f: print(f.read()) # In[42]: os.path.join("My Nice Folder", "myfile.txt") # In[43]: os.getcwd() # Будьте внимательны! Мир кодировок полон неожиданных сюрпризов, поэтому, всегда когда неуверены, при открытии файла на чтение или на запись прямо указывайте параметр **encoding=**, чтобы обозначить ту кодировку, которую хотите использовать. # In[2]: with open("russiantext.txt", "w", encoding="utf-8") as f: print("Раз два три четыре пять,", file=f) print("Вышел зайчик погулять!", file=f) # In[3]: with open("russiantext.txt", encoding='utf-8') as f: print(f.read()) # In[8]: with open("russiantext.txt", encoding='cp1251') as f: print(f.read())