Як видалити файл або папку?


Відповіді:


3342

PathОб'єкти з pathlibмодуля Python 3.4+ також піддають такі методи екземпляра:


5
os.rmdir () в Windows також видаляє символічне посилання каталогів, навіть якщо цільовий dir не порожній
Lu55

8
Якщо файл не існує, os.remove()викидає виняток, тому може знадобитися спочатку перевірити його os.path.isfile()або вкласти try.
Бен Кроуелл

2
Я хотів би, щоб Path.unlink 1 / був рекурсивним 2 / додав можливість ігнорувати FileNotfoundError.
Jérôme

7
тільки для завершення ... виняток, який викидає os.remove()файл, якщо файл не існує FileNotFoundError.
ПедроА

Чи os.remove() потрібно брати кілька аргументів для видалення декількох файлів, або ви викликаєте це кожен раз для кожного файлу?
користувач742864

292

Синтаксис Python для видалення файлу

import os
os.remove("/tmp/<file_name>.txt")

Або

import os
os.unlink("/tmp/<file_name>.txt")

Або

Бібліотека pathlib для версії Python> 3.5

file_to_rem = pathlib.Path("/tmp/<file_name>.txt")
file_to_rem.unlink()

Path.unlink (відсутність_ок = помилково)

Спосіб від’єднання, який використовується для видалення файлу або посилання symbolik.

Якщо false_ok невірно (за замовчуванням), FileNotFoundError піднімається, якщо шлях не існує.
Якщо true_ok вірно, винятки FileNotFoundError будуть ігноровані (така ж поведінка, як і команда POSIX rm -f).
Змінено у версії 3.8: Додано параметр отсутствующий_ok.

Найкраща практика

  1. Спочатку перевірте, чи існує файл чи папка чи не, а потім лише видаліть його. Цього можна досягти двома способами:
    a. os.path.isfile("/path/to/file")
    б. Використовуйтеexception handling.

ПРИКЛАД дляos.path.isfile

#!/usr/bin/python
import os
myfile="/tmp/foo.txt"

## If file exists, delete it ##
if os.path.isfile(myfile):
    os.remove(myfile)
else:    ## Show an error ##
    print("Error: %s file not found" % myfile)

Обробка винятків

#!/usr/bin/python
import os

## Get input ##
myfile= raw_input("Enter file name to delete: ")

## Try to delete the file ##
try:
    os.remove(myfile)
except OSError as e:  ## if failed, report it back to the user ##
    print ("Error: %s - %s." % (e.filename, e.strerror))

РЕСПЕКТИВНИЙ ВИХІД

Введіть ім'я файлу для видалення: demo.txt
Помилка: demo.txt - Немає такого файлу чи каталогу.

Введіть ім'я файлу для видалення: rrr.txt
Помилка: rrr.txt - Операція не дозволена.

Введіть ім'я файлу для видалення: foo.txt

Синтаксис Python для видалення папки

shutil.rmtree()

Приклад для shutil.rmtree()

#!/usr/bin/python
import os
import sys
import shutil

# Get directory name
mydir= raw_input("Enter directory name: ")

## Try to remove tree; if failed show an error using try...except on screen
try:
    shutil.rmtree(mydir)
except OSError as e:
    print ("Error: %s - %s." % (e.filename, e.strerror))

13
Обробку винятків рекомендується проводити під час перевірки, оскільки файл можна було видалити або змінити між двома рядками (TOCTOU: en.wikipedia.org/wiki/Time_of_check_to_time_of_use ) Див. Питання щодо
Ерік Арауджо

84

Використовуйте

shutil.rmtree(path[, ignore_errors[, onerror]])

(Дивіться повну документацію на shutil ) та / або

os.remove

і

os.rmdir

(Повна документація на ос .)


6
Будь ласка, додайте до свого списку інтерфейс pathlib (новий з Python 3.4).
Paebbels

38

Ось надійна функція, яка використовує і те, os.removeі shutil.rmtree:

def remove(path):
    """ param <path> could either be relative or absolute. """
    if os.path.isfile(path) or os.path.islink(path):
        os.remove(path)  # remove the file
    elif os.path.isdir(path):
        shutil.rmtree(path)  # remove dir and all contains
    else:
        raise ValueError("file {} is not a file or dir.".format(path))

8
Тобто 8 рядків коду для імітації remove(path);виклику ISO C.
Каз

2
@Kaz погодився дратувати, але чи видаляє справу з деревами? :-)
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

5
os.path.islink(file_path): помилка, має бутиos.path.islink(path):
Neo li

32

Ви можете використовувати вбудований pathlib модуль (вимагає Python 3.4+, але є Backports для старіших версій на PyPI: pathlib, pathlib2).

Для видалення файлу є unlink метод:

import pathlib
path = pathlib.Path(name_of_file)
path.unlink()

Або rmdirспосіб видалення порожньої папки:

import pathlib
path = pathlib.Path(name_of_folder)
path.rmdir()

2
А як з не порожнім каталогом?
Пранасас

@Pranasas На жаль, здається, немає нічого (вродженого), pathlibщо може обробляти видалення непорожніх каталогів. Однак ви можете використовувати shutil.rmtree. Про це було сказано в кількох інших відповідях, тому я не включив його.
MSeifert

29

Як видалити файл або папку в Python?

Для Python 3, щоб видалити файл та каталог окремо, використовуйте методи unlinkта об'єкт відповідно:rmdir Path

from pathlib import Path
dir_path = Path.home() / 'directory' 
file_path = dir_path / 'file'

file_path.unlink() # remove file

dir_path.rmdir()   # remove directory

Зауважте, що ви також можете використовувати відносні шляхи з Pathоб'єктами, і ви можете перевірити поточний робочий каталог Path.cwd.

Щоб видалити окремі файли та каталоги в Python 2, див. Розділ, зазначений нижче.

Щоб видалити каталог із вмістом, використовуйте shutil.rmtreeта зауважте, що це доступно в Python 2 та 3:

from shutil import rmtree

rmtree(dir_path)

Демонстрація

Новим у Python 3.4 є Path об’єкт.

Давайте використаємо один для створення каталогу та файлу для демонстрації використання. Зауважте, що ми використовуємо /для приєднання частин шляху, це допомагає вирішувати проблеми між операційними системами та проблеми використання зворотних косих рисок в Windows (де вам потрібно буде подвоїти ваші риски на зразок \\або використовувати необроблені рядки, як-от r"foo\bar"):

from pathlib import Path

# .home() is new in 3.5, otherwise use os.path.expanduser('~')
directory_path = Path.home() / 'directory'
directory_path.mkdir()

file_path = directory_path / 'file'
file_path.touch()

і зараз:

>>> file_path.is_file()
True

Тепер видалимо їх. Спочатку файл:

>>> file_path.unlink()     # remove file
>>> file_path.is_file()
False
>>> file_path.exists()
False

Ми можемо використовувати глобул для видалення кількох файлів - спочатку давайте створимо для цього кілька файлів:

>>> (directory_path / 'foo.my').touch()
>>> (directory_path / 'bar.my').touch()

Тоді просто повторіть схему:

>>> for each_file_path in directory_path.glob('*.my'):
...     print(f'removing {each_file_path}')
...     each_file_path.unlink()
... 
removing ~/directory/foo.my
removing ~/directory/bar.my

Тепер, демонструючи видалення каталогу:

>>> directory_path.rmdir() # remove directory
>>> directory_path.is_dir()
False
>>> directory_path.exists()
False

Що робити, якщо ми хочемо видалити каталог і все в ньому? Для цього випадку використанняshutil.rmtree

Давайте відтворимо наш каталог і файл:

file_path.parent.mkdir()
file_path.touch()

і зауважте, що rmdirвиходить з ладу, якщо він порожній, тому rmtree так зручно:

>>> directory_path.rmdir()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "~/anaconda3/lib/python3.6/pathlib.py", line 1270, in rmdir
    self._accessor.rmdir(self)
  File "~/anaconda3/lib/python3.6/pathlib.py", line 387, in wrapped
    return strfunc(str(pathobj), *args)
OSError: [Errno 39] Directory not empty: '/home/username/directory'

Тепер імпортуйте rmtree та передайте каталог у функцію:

from shutil import rmtree
rmtree(directory_path)      # remove everything 

і ми бачимо, що вся справа була видалена:

>>> directory_path.exists()
False

Пітон 2

Якщо ви перебуваєте на Python 2, є резервний модуль pathlib під назвою pathlib2 , який можна встановити за допомогою pip:

$ pip install pathlib2

І тоді ви можете створити псевдонім для бібліотеки pathlib

import pathlib2 as pathlib

Або просто імпортуйте Pathоб'єкт (як показано тут):

from pathlib2 import Path

Якщо це занадто багато, ви можете видалити файли за допомогою os.removeабоos.unlink

from os import unlink, remove
from os.path import join, expanduser

remove(join(expanduser('~'), 'directory/file'))

або

unlink(join(expanduser('~'), 'directory/file'))

і ви можете видалити каталоги за допомогою os.rmdir:

from os import rmdir

rmdir(join(expanduser('~'), 'directory'))

Зауважте, що є також os.removedirs- він видаляє лише порожні каталоги рекурсивно, але це може відповідати вашому випадку використання.


rmtree(directory_path)працює в python 3.6.6, але не в python 3.5.2 - вам це потрібно rmtree(str(directory_path))).
Штейн

4
import os

folder = '/Path/to/yourDir/'
fileList = os.listdir(folder)

for f in fileList:
    filePath = folder + '/'+f

    if os.path.isfile(filePath):
        os.remove(filePath)

    elif os.path.isdir(filePath):
        newFileList = os.listdir(filePath)
        for f1 in newFileList:
            insideFilePath = filePath + '/' + f1

            if os.path.isfile(insideFilePath):
                os.remove(insideFilePath)

1
Це видалить лише файли всередині папки та підпапки, залишивши недоторканою структуру папки ..
Lalithesh

4

shutil.rmtree - це асинхронна функція, тому якщо ви хочете перевірити, коли вона завершена, ви можете використовувати цикл ...

import os
import shutil

shutil.rmtree(path)

while os.path.exists(path):
  pass

print('done')

1
shutil.rmtreeне повинен бути асинхронним. Однак, можливо, це є у Windows, коли сканери вірусів заважають.
mhsmith

@mhsmith Сканери вірусів ? Це дикі міркування, чи ви насправді знаєте, що вони можуть спричинити цей ефект? Як на землі це працює, якщо так?
Марк Амері

2

Для видалення файлів:

os.unlink(path, *, dir_fd=None)

або

os.remove(path, *, dir_fd=None)

Обидві функції семантично однакові. Ця функція видаляє (видаляє) шлях до файлу. Якщо шлях не є файлом, а він є каталогом, тоді виключається виняток.

Для видалення папок:

shutil.rmtree(path, ignore_errors=False, onerror=None)

або

os.rmdir(path, *, dir_fd=None)

Для того, щоб видалити цілі дерева каталогів, shutil.rmtree()можна використовувати. os.rmdirпрацює лише тоді, коли каталог порожній і існує.

Для рекурсивного видалення папок у напрямку батьків:

os.removedirs(name)

Він видаляє кожен порожній батьківський каталог із self до батьків, який має деякий вміст

колишній os.removedirs ('abc / xyz / pqr') видалить каталоги на замовлення 'abc / xyz / pqr', 'abc / xyz' та 'abc', якщо вони порожні.

Для отримання додаткової інформації ознайомтеся офіційний документ: os.unlink, os.remove, os.rmdir, shutil.rmtree,os.removedirs


1

Щоб видалити всі файли в папці

import os
import glob

files = glob.glob(os.path.join('path/to/folder/*'))
files = glob.glob(os.path.join('path/to/folder/*.csv')) // It will give all csv files in folder
for file in files:
    os.remove(file)

Щоб видалити всі папки в каталозі

from shutil import rmtree
import os

// os.path.join()  # current working directory.

for dirct in os.listdir(os.path.join('path/to/folder')):
    rmtree(os.path.join('path/to/folder',dirct))

0

Щоб уникнути проблеми TOCTOU, підкресленої коментарем Еріка Арауджо , ви можете скористатися винятком, щоб викликати правильний метод:

def remove_file_or_dir(path: str) -> None:
    """ Remove a file or directory """
    try:
        shutil.rmtree(path)
    except NotADirectoryError:
        os.remove(path)

Так shutil.rmtree()як вилучатимуть лише каталоги та / os.remove()або os.unlink()будуть видаляти лише файли.


shutil.rmtree()видаляє не тільки каталог, але і його вміст.
Tiago Martins Peres 李大仁

-1

Я рекомендую використовувати, subprocessякщо писати гарний і читабельний код - ваша чашка чаю:

import subprocess
subprocess.Popen("rm -r my_dir", shell=True)

А якщо ви не програмний інженер, то, можливо, подумайте про використання Юпітера; ви можете просто ввести bash команди:

!rm -r my_dir

Традиційно ви використовуєте shutil:

import shutil
shutil.rmtree(my_dir) 

3
Підпроцесу - це практика, якої слід уникати
dlewin

3
Я б не рекомендував subprocessцього. shutil.rmtreeЧи має rm -r«s робота просто відмінно, з додатковим бонусом роботи на Windows.
Марк Амері
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.