Модули os, shutil и shelve

/notes/os_shutil_shelve/feature.png

Конспект посвящён модулям os и shutil, которые могут быть полезны для работы с операционной системой, управлением каталогами и файлами, а также модулю shelve, позволяющему сериализовывать объекты Python

Модуль os

Для использования: import os

Модуль os позволяет взаимодействовать с операционной системой. Например, мы можем перемещаться по папкам, получить информацию о файле, посмотреть и изменить переменные среды (окружения), переместить файлы и так далее. Посмотрим на некоторые функции и объекты, которые мы можем использовать.

  • os.getcwd() возвращает рабочий каталог (тот, в котором пользователь сейчас находится).

  • os.chdir(path) перемещает пользователя в директорию, которая была передана в функцию.

  • os.listdir(path) возвращает случайно упорядоченный список файлов и каталогов, которые находятся в текущем каталоге (если ничего не было передано), либо список объектов в директории по переданному пути.

  • os.scandir(path) возвращает итератор объектов os.DirEntry, представленные в виде записей каталога path.
    os.DirEntry — класс, объекты которого являются файлами или каталогами. Рассмотрим некоторые атрибуты и методы.

    • obj.name — имя файла/каталога;
    • obj.path — путь к файлу/каталогу, который будет начинаться с папки, переданной в пути os.scandir() первой;
    • obj.is_dir() возвращает True, если obj является папкой, иначе — False;
    • obj.is_file() возвращает True, если obj является файлом, иначе — False;
    • obj.stat() возвращает объект os.stat_result (см. ниже) для obj, как если бы была вызвана os.stat(path) (см. ниже), где obj является конечным в path.
  • os.mkdir(path) создаёт одну(!) папку, путь которой был передан в функцию.

Опасность
При попытке создать папку, которая уже присутствует в текущем каталоге, возвращает ошибку (исключение) FileExistsError, а если путь не найден, ошибку (исключение) FileNotFoundError. В дальнейшем упоминания об этих ошибках будут зачастую опускаться, где это совсем очевидно
  • os.makedirs(path, exist_ok=False) рекурсивно создаёт папки, путь которых был передан в качестве аргумента, то есть в отличии от mkdir(), функция makedirs() создаёт все папки промежуточного уровня, которые должны содержать конечный каталог. Параметр exist_ok имеет значение False по умолчанию, при котором в случае наличия одноимённой папки в рабочей директории функция вернёт ошибку FileExistsError, но если задать exist_ok=True, функция проигнорирует создание папки и не вернёт ошибку.

  • os.rm_dir(path) удаляет папку по переданному пути, если она пуста. В ином случае вернёт ошибку, зависящую от ОС , внутри которой ведётся работа (OSError).

  • os.removedirs(path) рекурсивно удаляет каталоги, начиная с последнего указанного в пути. Если какая-то из папок в пути окажется непустой, вызывает ошибку OSError, которая игнорируется.

  • os.remove(path) удаляет файл в пути path. Если передана папка, или файл не существует, возвращает соответствующие ошибки.

  • os.rename(src, dst) переименовывает файл или пустую папку с src на dst (могут быть представлены как пути), причём если указать файлу другой путь, он будет перемещён в него.

  • os.replace(src, dst) по функционалу аналогичен os.rename(), но для поддержки кроссплатформенности рекомендуется использовать именно os.replace().

  • os.chown(path, uid, gid) меняет идентификатор владельца объекта по пути path на числовые uid, gid. Чтобы изменить владельца по имени пользователя/группы, обратитесь к функции shutil.chown() модуля shutil

  • os.stat(path) возвращает объект stat_result, который содержит разного рода информацию о файле или папке. Рассмотрим атрибуты этого объекта:

    • st_mode: Режим файла: тип файла и биты режима файла (разрешения).
    • st_ino: Зависит от платформы, но если значение не равно нулю, однозначно идентифицирует файл по заданному значению st_dev. inode номер для Unix; индекс файла для Windows.
    • st_dev: Идентификатор устройства, в котором находится файл.
    • st_nlink: Количество жёстких ссылок.
    • st_uid: Идентификатор пользователя владельца файла.
    • st_gid: Идентификатор группы пользователей владельцев файла.
    • st_size: Размер файла в байтах, если это обычный файл или символьная ссылка. Размер символьной ссылки - это длина пути, который она содержит, без завершающего нулевого байта.
    • st_atime: Время последнего доступа в секундах.
    • st_mtime: Время последней модификации содержимого в секундах.
    • st_ctime: Время последнего изменения метаданных в секундах.
    • st_birthtime: Время создания файла. Атрибут доступен не всегда и может вызвать ошибку (исключение) AttributeError.
    • и другие.
  • os.walk(top, topdown=True, onerror=False) генерирует дерево каталогов, начиная с top (либо с конца до top, если topdown=False). Для каждого каталога в дереве возвращает кортеж (dirpath, dirnames, filenames), где dirpath — путь к каталогу, dirnames — список имён подкаталогов в dirpath и filenames — список имён файлов в dirpath.

1
2
3
4
5
6
7
import os

for dirpath, dirnames, filenames in os.walk("Test_walk"):
    print("Current path:", dirpath)
    print("Directories:", dirnames)
    print("Files:", filenames)
    print()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Вывод:
Current path: Test_walk
Directories: ['P', 'R']
Files: ['Risunok.bmp']

Current path: Test_walk\P
Directories: []
Files: ['kek.txt', 'L.txt']

Current path: Test_walk\R
Directories: []
Files: []
  • os.system(command) выполняет переданную команду command, будто она написана в терминале. Таким образом можно создавать файлы папки, перемещаться по каталогам и т.д. Если команда сгенерирует какой-либо вывод, он будет перенаправлен в поток вывода интерпретатора. В Windows возвращаемое значение равно значению, возвращаемому системной оболочкой после выполнения команды (задаётся переменной среды COMSPEC: обычно cmd.exe)

  • os.environ — объект, подобный словарю (mapping object), содержащий переменные среды окружения системы.

  • os.sep — разделитель пути в операционной системе. '/' для POSIX и '\\' для Windows

Подмодуль os.path

  • os.path.split(path) разбивает переданный путь на парный кортеж (head, tail), где tail — последний компонент пути (всегда без косой черты), а head — всё остальное. При этом: если path завершился косой чертой, tail будет пуст; если в path нет ни одной косой черты, head будет пуст; если path пуст, оба элемента кортежа будут пустыми.

  • os.path.splitext(path) разбивает переданный путь на парный кортеж (root, ext), где root + ext = path и ext — расширение файла с точкой, а root — всё остальное.

  • os.path.dirname(path) возвращает первый элемент кортежа от функции os.path.split(), то есть путь до конечного файла/каталога не включая.

  • os.path.basename(path) возвращает второй элемент кортежа от функции os.path.split(), то есть имя конечного файла/каталога.

  • os.path.join(path, *paths) объединяет один или несколько сегментов пути. Возвращает строку, состоящую из объединения path и всех элементов *paths, которые разделяются os.sep, кроме последнего (если тот не пуст).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import os.path
os.path.join('home', 'User', 'Desktop', 'file.txt')
# 'home/User/Desktop/file.txt'

os.path.join('/home', 'User/Desktop', 'file.txt')
# '/home/User/Desktop/file.txt'

os.path.join('/home', '/User/Desktop', 'file.txt')
# '/User/Desktop/file.txt'

os.path.join('User/Desktop', '/home', 'file.txt')
# '/home/file.txt'
  • os.path.exists(path) возвращает True, если path ссылается на существующий путь, иначе — False.

  • os.path.isabs(path) возвращает True, если путь является абсолютным, иначе — False. В случае отсутствия пути возвращает исключение OSError.

  • os.path.isdir(path) возвращает True, если путь существует и является каталогом, иначе — False.

  • os.path.isfile(path) возвращает True, если путь существует и является файлом, иначе — False.

  • os.path.abspath(path) возвращает абсолютный путь.


Модуль shutil

Модуль shutil предлагает ряд высокоуровневых операций с файлами и коллекциями файлов. Например функции, которые поддерживают копирование и удаление файлов. Разберём основные возможности этого модуля.

Предупреждение
Даже функции копирования файлов более высокого уровня (shutil.copy(), shutil.copy2()) не могут скопировать все метаданные файла. Например в Windows, владельцы файлов, списки контроля доступа и альтернативные потоки данных не копируются.
  • shutil.copy(src, dst) копирует файла src в файл или директорию dst, при этом оба аргумента передаются как пути.

  • shutil.copy2(src, dst) идентична функции copy(), за исключением того, что функция copy2() также пытается сохранить метаданные файла.

  • shutil.copyfileobj(fsrc, fdst) копирует содержимое файла srcfsrc (получается, например, при открытии файла с помощью open()) в объект файла fdst.

  • shutil.ignore_patterns(*patterns) создаёт функцию, которая может быть использована в качестве аргумента для параметра ignore функции shutil.copytree() (см. ниже). В результате файлы и каталоги, подходящие под (хотя бы) один из переданных шаблонов будут игнорироваться при копировании.

  • shutil.copytree(src, dst, dirs_exist_ok=False, ignore=None) рекурсивно копирует дерево каталогов из папки src в папку dst и возвращает dst. Если установить dirs_exist_ok=True, исключение вызвано НЕ БУДЕТ, если целевой каталог с именем dst уже существует.
    Если задано значение ignore, то это должен быть вызываемый объект, который получит в качестве своих аргументов текущий каталог, посещаемый функцией copytree(), и список его содержимого, возвращаемый функцией os.listdir(), например функция, возвращаемая shutil.ignore_patterns() или самописная функция.

  • shutil.rmtree(path) удаляет дерево каталогов по переданному пути.

  • shutil.copymode(src, dst) копирует права доступа с файла по пути src в файл dst.

  • shutil.copystat(src, dst) копирует время последнего доступа, время последнего изменения и флаги(чтение, запись и т.д.) из src в dst.

  • shutil.move(src, dst, copy_function=copy2) рекурсивно перемещает файл или директорию src в директорию dst и возвращает dst. Если место назначения dst находится в текущей файловой системе, тогда неявно используется функция os.rename(). В противном случае src копируется в dst с помощью функции, переданной в аргумент copy_function, а затем удаляется.

  • shutil.which(path) возвращает абсолютный путь к исполняемому файлу, путь которых прописан в PATH (переменные среды)

  • shutil.disk_usage(path) возвращает статистику использования диска по указанному пути в виде именованного кортежа с атрибутами total — общий объём диска, used — используемый объём и free — свободное пространство в байтах.

  • shutil.chown(path, user=None, group=None) меняет владельца объекта по пути path на user и group. user может быть системным именем пользователя или uid; то же самое относится и к group. Требуется как минимум один аргумент.

  • shutil.make_archive(name, format, root_dir) создаёт архивный файл папки/файла root_dir с именем name (может быть указан как путь) в формате format и возвращает name.

  • shutil.unpack_archive(filename, extract_dir) распаковывает архив с именем filename в папку extract_dir.

  • shutil.get_archive_formats() возвращает список всех поддерживаемых форматов архивов.


Модуль shelve

Модуль shelve сохраняет произвольные объекты Python в файл с определенным ключом (типа str), т.е. такие объекты, которые может обработать модуль pickle (большинство экземпляров классов, рекурсивных типов данных и объектов, содержащих множество общих подобъектов). Затем по этому ключу может извлечь ранее сохраненный объект из файла. В отличии от pickle, shelve более удобен, когда требуется сериализовать множество объектов.

Функция shelve.open()

shelve.open(filename, flag='c') возвращает объект key-value хранилища, похожий на словарь (объект называется shelf). В filename передаётся имя открываемого/создаваемого файла, flag принимает одно из следующих значений:

  • 'c' — файл открывается для чтения и записи. Если файл отсутствует, он создаётся;
  • 'r' — файл открывается для чтения;
  • 'w' — файл открывается для записи;
  • 'n' — файл открывается для для записи. Если файл отсутствует, он создаётся. Если существует, перезаписывается.

Объекты shelf поддерживают большинство методов и операций, поддерживаемых словарями (за исключением копирования, конструкторов и операторов | и |=). Запись/чтение данных shelf также происходит подобно записи/чтению данных словаря. Посмотрим пример:

1
2
3
4
5
6
7
8
import shelve

with shelve.open('test') as db:
    db['func'] = func
    db['not_string'] = {"this_is_not_string_LOL": 80085}
    print(db['not_string'])

# Вывод: {'this_is_not_string_LOL': 80085}

Программа создаёт три файла разных расширений: dat, bak, dir, в которых содержится одна и та же сериализованная протоколом pickle информация.

Предупреждение
Не стоит открывать незнакомые pkl файлы и файлы, которые создаются shelve, поскольку они могут содержать самовыполняющийся код
Поддержать автора
NoisyCake cloudtipscloudtips
0%