我有一些目录要删除,但其中一个目录有一个我想保留的子目录。
示例:
文件
图片
cat.png
的icon.png
音乐
Song.mp3的
影
First.mp4
我想删除除子目录图片之外的所有内容(目录和子目录)。
现在我有这个:
def Destroy_Path(path):
shutil.rmtree(path, ignore_errors=True)
答案 0 :(得分:0)
这是一个解决方案。的 UNTESTED! 强>
请注意使用os.walk()
能够就地更改dirnames
以告诉它不要递归到子目录,并避免使用topdown=False
这将打破这个功能:
当 topdown 为
True
时,调用者可以就地修改dirnames列表 (可能使用del
或切片分配),而walk()
只会递归 进入名称保留在 dirnames 中的子目录;这可以 用于修剪搜索,[...] topdown 为False
时修改 dirnames 对walk的行为没有影响,因为在自下而上模式下 dirnames 在 dirpath 生成之前生成。
有关详细信息,请参阅the docs。
另外值得注意的是使用os.path.samefile()
进行路径比较。这是available on Windows since version 3.2。
这是未经测试的!
自行承担风险!!
严重,小心!!!
import os
def gen_dir_paths_except(base_path, exceptions):
# behave like os.walk(): return nothing if the given path isn't a directory
if not os.path.isdir(base_path):
return
# keep only existing paths in exceptions, so that os.path.samefile() works
exceptions = list(filter(os.path.exists, exceptions))
# don't forget the base directory
if any(os.path.samefile(base_path, x) for x in exceptions):
return
yield base_path
for curr_dirpath, dirnames, filenames in os.walk(base_path):
# skip directories mentioned in exceptions
dirnames_to_skip = []
for dir_name in dirnames:
dir_path = os.path.join(curr_dirpath, dir_name)
if any(os.path.samefile(dir_path, x) for x in exceptions):
dirnames_to_skip.append(dir_name)
else:
yield dir_path
for dir_name in dirnames_to_skip:
dirnames.remove(dir_name)
def rmtree_except(path, exceptions):
# Check that the path is actually a directory. This is needed here
# because os.walk() will silently return nothing for a non-directory.
if not os.path.isdir(path):
if not os.path.exists(path):
raise OSError("No such directory: " + path)
else:
raise OSError("Not a directory: " + path)
# keep only existing paths in exceptions, so that os.path.samefile() works
exceptions = list(filter(os.path.exists, exceptions))
dirs = list(gen_dir_paths_except(path, exceptions))
# iterate through directories in bottom-up order
for dir_path in reversed(dirs):
filenames = [
x for x in os.listdir(dir_path)
if not os.path.isdir(os.path.join(dir_path, x))
]
for file_name in filenames:
# skip files mentioned in exceptions
file_path = os.path.join(dir_path, file_name)
if not any(os.path.samefile(file_path, x) for x in exceptions):
os.remove(file_path)
try:
os.rmdir(dir_path)
except OSError: # directory not empty
pass # just leave the directory