การลบโฟลเดอร์ในหลามแบบวนซ้ำ


202

ฉันมีปัญหาในการลบไดเรกทอรีว่าง นี่คือรหัสของฉัน:

for dirpath, dirnames, filenames in os.walk(dir_to_search):
    //other codes

    try:
        os.rmdir(dirpath)
    except OSError as ex:
        print(ex)

ข้อโต้แย้งdir_to_searchคือที่ที่ฉันผ่านไดเรกทอรีที่งานต้องทำ ไดเรกทอรีนั้นมีลักษณะดังนี้:

test/20/...
test/22/...
test/25/...
test/26/...

โปรดทราบว่าโฟลเดอร์ด้านบนทั้งหมดว่างเปล่า เมื่อฉันเรียกใช้สคริปต์นี้โฟลเดอร์20, 25อยู่คนเดียวได้รับการลบ! แต่โฟลเดอร์25และ26ไม่ถูกลบแม้ว่าจะเป็นโฟลเดอร์เปล่า

แก้ไข:

ข้อยกเว้นที่ฉันได้รับคือ:

[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/26'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/25'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27/tmp'

ฉันทำผิดพลาดที่ไหน


1
คุณแน่ใจหรือว่าพวกเขาไม่มีไฟล์ที่ซ่อนอยู่
Jeff

เป็นข้อยกเว้นหรือพิมพ์ย้อนกลับ? ถ้าเป็นเช่นนั้น - มันจะช่วยได้ถ้าคุณเพิ่มคำถามลงไป
Ngure Nyaga

@Jeff: ใช่ฉันแน่ใจ อันที่จริงแล้วในเครื่องอูบุนตูฉันพยายามrmdir /path/to/25th/folderลบไดเรกทอรีทั้งหมด ซึ่งหมายความว่าไดเรกทอรีนั้นว่างเปล่า!
sriram

2
ซ้ำกันเป็นไปได้ของฉันจะลบ / ลบโฟลเดอร์ที่ไม่ว่างกับ Python ได้อย่างไร ของคำถามและคำตอบทั้งสอง
Trevor Boyd Smith

คำตอบ:


392

ลองshutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')

5
ที่ไม่rmtreeถูกลบไดเรกทอรีทั้งหมด? ฉันเดาว่ามันคล้ายกับ onerm -Rf $DIR
sriram

7
ระวังด้วย rmtree ลบไฟล์ด้วย ตามที่ถามแล้วคำถามคือวิธีการลบไดเรกทอรีที่ว่างเปล่าเอกสารสำหรับ os.walk ให้ตัวอย่างที่ตรงกับคำถามนี้เกือบทั้งหมด: import os for root, dirs, files in os.walk(top, topdown=False): for name in dirs: os.rmdir(os.path.join(root, name))
DaveSawyer


27

พฤติกรรมเริ่มต้นของos.walk()คือการเดินจากรากถึงใบไม้ ตั้งtopdown=Falseในที่os.walk()จะเดินจากใบไม้เพื่อรูต


18

นี่คือpathlibunlinker ไดเรกทอรีบริสุทธิ์ของฉัน:

from pathlib import Path

def rmdir(directory):
    directory = Path(directory)
    for item in directory.iterdir():
        if item.is_dir():
            rmdir(item)
        else:
            item.unlink()
    directory.rmdir()

rmdir(Path("dir/"))

12

ลองrmtree()ในshutilจากห้องสมุดมาตรฐานหลาม


1
ที่ไม่rmtreeถูกลบไดเรกทอรีทั้งหมด? ฉันเดาว่ามันคล้ายกับ onerm -Rf $DIR
sriram

2
จาก docs: "ลบทรีไดเรกทอรีทั้งหมดพา ธ ต้องชี้ไปที่ไดเรกทอรี (แต่ไม่ใช่ลิงก์สัญลักษณ์ไปยังไดเรกทอรี) หากไม่ได้ระบุความผิดพลาดที่เป็นจริงข้อผิดพลาดที่เกิดจากการลบที่ล้มเหลวจะถูกจัดการหากเป็นเท็จหรือละเว้น โดยการเรียกตัวจัดการที่ระบุโดย onerror หรือหากไม่ได้ระบุไว้พวกมันจะยกข้อยกเว้น "
microo8

7

ดีกว่าที่จะใช้เส้นทางที่แน่นอนและนำเข้าเฉพาะฟังก์ชั่น rmtree from shutil import rmtree เช่นนี้เป็นแพคเกจขนาดใหญ่บรรทัดข้างต้นจะนำเข้าเฉพาะฟังก์ชั่นที่ต้องการ

from shutil import rmtree
rmtree('directory-absolute-path')

1
จากนั้นคุณจะอ้างอิงสิ่งนี้เป็นrmtree(); ไม่ใช่shutil.rmtree()
Kevin Murphy

4

เพียงแค่สำหรับคนต่อไปที่กำลังมองหาโซลูชัน micropython มันทำงานได้อย่างหมดจดจากระบบปฏิบัติการ (listdir, remove, rmdir) มันไม่สมบูรณ์ (โดยเฉพาะอย่างยิ่งในการจัดการข้อผิดพลาด) หรือแฟนซีมันจะทำงานในสถานการณ์ส่วนใหญ่

def deltree(target):
    print("deltree", target)
    for d in os.listdir(target):
        try:
            deltree(target + '/' + d)
        except OSError:
            os.remove(target + '/' + d)

    os.rmdir(target)

3

คำสั่ง (กำหนดโดย Tomek) ไม่สามารถลบ ไฟล์หากมีการอ่านเท่านั้น ดังนั้นหนึ่งสามารถใช้ -

import os, sys
import stat

def del_evenReadonly(action, name, exc):
    os.chmod(name, stat.S_IWRITE)
    os.remove(name)

if  os.path.exists("test/qt_env"):
    shutil.rmtree('test/qt_env',onerror=del_evenReadonly)

2
NameError: name 'stat' is not definedเมื่อพยายามรหัสของคุณกับโฟลเดอร์ของตัวเองที่จะถูกลบฉันได้รับข้อผิดพลาดว่า: มันถูกกำหนดอย่างไร?
nnako

1
โมดูล stat กำหนดค่าคงที่และฟังก์ชันสำหรับการตีความผลลัพธ์ของ os.stat (), os.fstat () และ os.lstat () คุณสามารถลองอะไรได้บ้าง: import os, sys จาก stat import *
Monir

0

นี่เป็นอีกวิธีการแก้ปัญหา pathlib บริสุทธิ์แต่ไม่มีการเรียกซ้ำ:

from pathlib import Path
from typing import Union

def del_empty_dirs(base: Union[Path, str]):
    base = Path(base)
    for p in sorted(base.glob('**/*'), reverse=True):
        if p.is_dir():
            p.chmod(0o666)
            p.rmdir()
        else:
            raise RuntimeError(f'{p.parent} is not empty!')
    base.rmdir()

-1

นี่คือโซลูชันแบบเรียกซ้ำ:

def clear_folder(dir):
    if os.path.exists(dir):
        for the_file in os.listdir(dir):
            file_path = os.path.join(dir, the_file)
            try:
                if os.path.isfile(file_path):
                    os.unlink(file_path)
                else:
                    clear_folder(file_path)
                    os.rmdir(file_path)
            except Exception as e:
                print(e)

-1

สำหรับผู้ใช้ Linux คุณสามารถรันคำสั่งเชลล์ในแบบ pythonic

import os
os.system("rm -r /home/user/folder_name")

ที่rmยืนสำหรับลบและ-rสำหรับซ้ำ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.