====== Работа с файловой системой ====== ===== Пути к файлам ===== В Windows пути: * Начинаются с имени диска (''C:'', ''D:'', ...) * Регистронезависимы (''Hello.txt'' и ''hello.txt'' один файл) * Компоненты пути разделяются символом ''\'' В POSIX системах пути: * Начинаются с корневой директории ''/'' * Регистрозависимы (''Hello.txt'' и ''hello.txt'' разные файлы) * Компоненты пути разделяются символом ''/'' Пути бывают: * Абсолютные (''C:\python\python.exe'', ''/usr/bin/python'') * Относительные (''..\python.exe'', ''../python'') * Со специальными сокращениями ''%WINDIR%\notepad.exe'', ''~/file.txt''
===== Работа с путями как со строками ===== Пути к файлам с точки зрения системы это текстовые строки. filepath = r"C:\Windows\notepad.exe" filepath = "/usr/bin/nano" - Просто - Всегда работает - Неперенасимо
===== Работа с путями как с объектами ===== from pathlib import Path p = Path(r"C:\Windows\notepad.exe") p.parts # ('C:', 'Windows', 'notepad.exe') p.parents[0] # PosixPath('C:/Windows') p.parents[1] # PosixPath('C:') - Сложнее - Иногда приходится приводить к строкам - Переносимо
===== Некоторые функции ===== === Основные модули для работы с путями === import os import os.path import shutil === Текущая папка скрипта === os.getcwd() # '/home/f0ma' os.chdir("/home/f0ma")
=== Пути абсолютные и относительные === os.getcwd() # '/home/f0ma' p1 = os.path.relpath("/home/f0ma/test.txt") # p1 == 'test.txt' p2 = os.path.relpath("/usr/bin/bash") # p2 == '../../usr/bin/bash' p3 = os.path.abspath('../../usr/bin/bash') # p3 == '/usr/bin/bash'
=== Компоненты пути === # Имя файла без пути p4 = os.path.basename("/home/f0ma/test.txt") # p4 == 'test.txt' # Путь без имени p5 = os.path.dirname("/home/f0ma/test.txt") # p5 == '/home/f0ma' # Компоненты пути p6 = os.path.normpath("/home/f0ma/test.txt").split(os.sep) # p6 == ['', 'home', 'f0ma', 'test.txt'] # Имя диска (только для Windows) p7, _ = os.path.splitdrive(r"C:\Windows\notepad.exe") # p7 == "C:" # Расширение файла (последнее) _, p8 = os.path.splitext(r"C:\Windows\notepad.exe") # p8 == ".exe"
==== Существование файлов и папок ==== # Существование файла s1 = os.path.isfile("/home/f0ma/test.txt") #s1 == True # Существование папки s2 = os.path.isdir("/home/f0ma") #s2 == True
==== Атрибуты файлов и папок ==== # Время создания t2 = os.path.getctime("/home/f0ma/test.txt") # t2 == 1509012699.5303257 # Время изменения t1 = os.path.getmtime("/home/f0ma/test.txt") # t1 == 1509012699.4743266 # Размер s = os.path.getsize("/home/f0ma/test.txt") # s == 18
==== Перемещение/копирование/удаление ==== # Создание одной папки os.mkdir("/home/f0ma/test") # Создание всех папок в пути os.makedirs("/home/f0ma/test/test") # Удаление файла os.remove("/home/f0ma/test/test.txt") # Удаление папки (пустой) os.rmdir("/home/f0ma/test") # Удаление папки с файлами рекурсивно shutil.rmtree("/home/f0ma/test") # Перемещения файла или папки shutil.move("/home/f0ma/test", "/tmp/test") # Копирование файла shutil.copy("/home/f0ma/test.txt", "/home/f0ma/test2.txt") # Копирование папки рекурсивно shutil.copytree("/home/f0ma/test", "/tmp/test")
==== Список файлов по маске ==== Обход по маске — метод ''glob'' модуля ''glob''. import glob import os os.chdir("/home/f0ma/src/hesk273/docs/") s1 = glob.glob("*.html") # s1 == ['/home/f0ma/src/hesk273/docs/changelog.html', # ... # '/home/f0ma/src/hesk273/docs/step-by-step-guide.html'] s2 = glob.glob("/home/f0ma/src/**/**/*.css") # s2 == ['/home/f0ma/src/pdfedit-0.4.5/doc/pdfedit.css', # ... # '/home/f0ma/src/hesk273/docs/docs_style.css'] ^ Символ маски ^ Значение ^ | ''*'' | Любое число любых символов | | ''?'' | Один любой символ | | ''**'' | Обойти все папки рекурсивно |
==== Обход файлов ==== Рекурсивный обход файлов метод ''walk'' модуля ''os''. import os for dirname, subdirs, files in os.walk("bin"): # dirname — имя текущей папки print(dirname) # subdirs — подпапки текущей папки print(subdirs) # files — файлы в текущей папке print(files)
==== Что еще нужно знать о путях ==== * Если путь не абсолютный, то он вычисляется от текущей папки программы. * Обход глубоко вложенных деревьев может занимать очень много времени. * Разные файловые системы (ФС) имеют различные особенности в частности атрибуты и альтернативные потоки. * В Windows и POSIX различная схема управления правами на доступ к файлам, а еще есть такие вещи, как SELinux и ACL. * Минимальный размер файла и папки ~ 4 КБ (зависит от ФС). * Можно получать уведомления об изменении файлов от ОС, но это платформозависимо (модули ''inotify''pip и ''watchdog''pip).