shutil Python

Содержание
Введение
Варианты копирования
copyfile
copy
move
Удалить содержимое директории
Похожие статьи

Введение

В этой статье вы узнаете как работать с несколькими файлами одновременно с помощью shutil.

Перед изучением данной статьи рекомендую убедиться, что вы знакомы с материалом из статьи os

Оффициальная документация

Копирование

copyfile() копирует только контент файла
copy() copyfile() + права доступа + назначением может быть директория
copy2() copy() + метадата (время создания и изменения файла)

copyfile

Синтаксис

shutil.copyfile(src, dst, *, follow_symlinks=True)

Описание

Копирует содержимое (без метаданных) файла с именем src в файл с именем dst и верните dst наиболее эффективным из возможных способов. src и dst - это объекты, подобные пути, или имена путей, заданные в виде строк.

dst должно быть полным именем целевого файла; посмотрите на copy() для получения копии, которая принимает путь к целевому каталогу. Если src и dst указывают один и тот же файл, возникает ошибка SameFileError.

Местоположение назначения должно быть доступно для записи; в противном случае будет вызвано исключение OSError. Если летнее время уже существует, оно будет заменено. Специальные файлы, такие как символьные или блочные устройства и каналы, не могут быть скопированы с помощью этой функции.

Если значение follow_symlinks равно false, а src является символической ссылкой, то вместо копирования файла, на который указывает src, будет создана новая символическая ссылка.

Вызывает событие аудита shutil.copyfile с аргументами src, dst.

Изменено в версии 3.3: раньше вызывался IOError вместо OSError. Добавлен аргумент follow_symlinks. Теперь возвращает летнее время.

Изменено в версии 3.4: Вызывается SameFileError вместо Error. Поскольку первый является подклассом второго, это изменение обратно совместимо.

Изменено в версии 3.8: Системные вызовы быстрого копирования, специфичные для конкретной платформы, могут использоваться внутри системы для более эффективного копирования файла. Смотрите раздел "Эффективные операции копирования, зависящие от платформы" .

Пример

shutil/ └── source.txt

cat source.txt

Welcome to www.eth1.ru/www.eth1.ru!

import shutil shutil.copyfile('source.txt', 'destination.txt')

Новый файл destination.txt появится в той же директории.

shutil/ ├── destination.txt └── source.txt

Проверить содержимое можно командой cat (в Linux и Unix ) или командой notepad (в Windows )

cat destination.txt

Welcome to www.eth1.ru/www.eth1.ru!

copy

Синтаксис

shutil.copy(src, dst, *, follow_symlinks=True)

Описание

Копирует файл src в файл или каталог dst.

src и dst должны быть объектами, подобными пути, или строками.

Если в качестве dst задан каталог, файл будет скопирован в dst, используя базовое имя файла из src.

Если в качестве dst указан файл, который уже существует, он будет заменен. Возвращает путь ко вновь созданному файлу.

Если значение follow_symlinks равно false, а src является символической ссылкой, dst будет создан как символическая ссылка.

Если значение follow_symlinks равно true и src является символической ссылкой, dst будет копией файла, на который ссылается src.

copy() копирует данные файла и режим разрешения файла (см. os.chmod()). Другие метаданные, такие как время создания и модификации файла, не сохраняются.

Чтобы сохранить все метаданные файла из оригинала, вместо этого используйте copy2().

Вызывает событие аудита shutil.copyfile с аргументами src, dst.

Вызывает событие аудита shutil.copymode с аргументами src, dst.

Изменено в версии 3.3: добавлен аргумент follow_symlinks. Теперь возвращает путь к вновь созданному файлу.

Изменено в версии 3.8: Системные вызовы быстрого копирования, специфичные для конкретной платформы, могут использоваться внутри системы для более эффективного копирования файла. Смотрите раздел "Эффективные операции копирования, зависящие от платформы".

Пример

Предположим, что мы находимся в директории python:

python/ ├── dir_a │ ├── Armenia.html │ ├── Finland.html │ ├── Spain │ └── Sweden.html └─ dir_b

import shutil import os src = "/mnt/c/Users/Andrei/sandbox/python/dir_a" dest = "/mnt/c/Users/Andrei/sandbox/python/dir_b" dir_a_files = os.listdir(src) print(dir_a_files) dir_b_files = os.listdir(dest) print(dir_b_files) os.chdir(src) for file in dir_a_files: with open(file) as f: print(file, f.read())

python shutil_ex.py

['Armenia.html', 'Finland.html', 'Spain', 'Sweden.html'] ['Armenia.html', 'Finland.html', 'Sweden.html'] Armenia.html tickets to Armenia hotels in Armenia Finland.html tickets to Finland hotels in Finland Traceback (most recent call last): File "/mnt/c/Users/Andrei/sandbox/python/shutil_ex1.py", line 16, in <module> with open(file) as f: ^^^^^^^^^^ IsADirectoryError: [Errno 21] Is a directory: 'Spain'

Открыть директорию как файл не получилось

import shutil import os src = "/mnt/c/Users/Andrei/sandbox/python/dir_a" dest = "/mnt/c/Users/Andrei/sandbox/python/dir_b" dir_a_files = os.listdir(src) print(dir_a_files) dir_b_files = os.listdir(dest) print(dir_b_files) os.chdir(src) for file in dir_a_files: shutil.copy(file, dest)

['Armenia.html', 'Finland.html', 'Spain', 'Sweden.html'] [] Traceback (most recent call last): File "/mnt/c/Users/Andrei/sandbox/python/shutil_ex.py", line 16, in <module> shutil.copy(file, dest) File "/usr/local/lib/python3.11/shutil.py", line 419, in copy copyfile(src, dst, follow_symlinks=follow_symlinks) File "/usr/local/lib/python3.11/shutil.py", line 256, in copyfile with open(src, 'rb') as fsrc: ^^^^^^^^^^^^^^^ IsADirectoryError: [Errno 21] Is a directory: 'Spain'

Несмотря на ошибку, вызванную невозможностью скопировать директорию, обычные файлы которые шли по списку раньше чем Spain успели скопироваться.

ls dir_b/

Armenia.html Finland.html

Чтобы не получать ошибки из-за директорий воспользуемся проверкой на тип файла os.paht.isfile которая может определить является ли файл обычным файлом а не директорией.

import shutil import os src = "/mnt/c/Users/Andrei/sandbox/python/dir_a" dest = "/mnt/c/Users/Andrei/sandbox/python/dir_b" dir_a_files = os.listdir(src) print(dir_a_files) dir_b_files = os.listdir(dest) print(dir_b_files) os.chdir(src) for file in dir_a_files: if os.path.isfile(file): shutil.copy(file, dest)

python shutil_ex.py

['Armenia.html', 'Finland.html', 'Spain', 'Sweden.html'] []

ls dir_b/

Armenia.html Finland.html Sweden.html

Если в директории назначения были файлы с такими же именами как у копируемых, то они будут перезаписаны.

move

for file in dir_a_files: if os.path.isfile(file): shutil.move(file, dest)

python shutil_ex.py

['Armenia.html', 'Finland.html', 'Spain', 'Sweden.html'] []

ls dir_a

Spain

ls dir_b

Armenia.html Finland.html Sweden.html

Если бы такие файлы уже были в директории назначения, то получилась бы ошибка

['Armenia.html', 'Finland.html', 'Spain', 'Sweden.html'] ['Armenia.html', 'Finland.html', 'Sweden.html'] Traceback (most recent call last): File "/mnt/c/Users/Andrei/sandbox/python/shutil_ex.py", line 18, in <module> shutil.move(file, dest) File "/usr/local/lib/python3.11/shutil.py", line 823, in move raise Error("Destination path '%s' already exists" % real_dst) shutil.Error: Destination path '/mnt/c/Users/Andrei/sandbox/python/dir_b/Armenia.html' already exists

Заставить файлы быть перезаписанными можно задав полные пути с помощью os.path.join()

import shutil import os src = "/mnt/c/Users/Andrei/sandbox/python/dir_a" dest = "/mnt/c/Users/Andrei/sandbox/python/dir_b" dir_a_files = os.listdir(src) print(dir_a_files) dir_b_files = os.listdir(dest) print(dir_b_files) os.chdir(src) for file in dir_a_files: if os.path.isfile(file): print(dest) full_dest = os.path.join(dest, file) print(full_dest) print() shutil.move(file, full_dest)

['Armenia.html', 'Finland.html', 'Spain', 'Sweden.html'] ['Armenia.html', 'Finland.html', 'Sweden.html'] /mnt/c/Users/Andrei/sandbox/python/dir_b /mnt/c/Users/Andrei/sandbox/python/dir_b/Armenia.html /mnt/c/Users/Andrei/sandbox/python/dir_b /mnt/c/Users/Andrei/sandbox/python/dir_b/Finland.html /mnt/c/Users/Andrei/sandbox/python/dir_b /mnt/c/Users/Andrei/sandbox/python/dir_b/Sweden.html

ls dir_a

Spain

ls dir_b

Armenia.html Finland.html Sweden.html

Удалить содержимое директории

Чтобы очистить директорию с помощью Python нужно воспользоваться shutil и os

import shutil import os def delete_dir_content(path: str): for file in os.listdir(path): file_path = os.path.join(path, file) try: if os.path.isfile(file_path) or os.path.islink(file_path): os.unlink(file_path) elif os.path.isdir(file_path): shutil.rmtree(file_path) except Exception as e: print(f"Failed to delete {file_path}. Reason: {e}")

Про deep copy и shallow copy в программировании можно прочитать здесь

Про функцию copy() в Python можно прочитать здесь

Похожие статьи
Работа с файлами в Python
Python
Основы работы с файлами
Продвинутые приёмы
glob: Работа с несколькими файлами
os
pathlib
Скачать файл по сети
.yaml.json
psutil: cистемные ресурсы
Обучение программированию на Python
Изображение баннера

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: