如何删除目录树中所有的 __pycache__ 文件夹

3

在我的模拟过程中,Python会创建名为__pycache__的文件夹。不仅是一个,而是很多个。这些__pycache__文件夹几乎总是在执行的模块旁边创建。

但是这些模块在我的目录中是分散的。主文件夹名为LPG,有很多子文件夹,这些子文件夹又有进一步的子文件夹。这些__pycache__文件夹可能出现在所有可能的位置。

在模拟结束时,我想清理并删除LPG-树内所有名为__pycache__的文件夹。

最好的做法是什么?

目前,我在模拟结束时(也在模拟开始时)调用下面的函数。然而,这有点麻烦,因为我必须明确写下每个可能出现__pycache__文件夹的路径。

def clearCache():
    """
    Removes generic `__pycache__` .

    The `__pycache__` files are automatically created by python during the simulation.
    This function removes the generic files on simulation start and simulation end.
    """
    try:
        shutil.rmtree(Path(f"{PATH_to_folder_X}/__pycache__"))
    except:
        pass

    try:
        shutil.rmtree(Path(f"{PATH_to_folder_Y}/__pycache__"))
    except:
        pass

这个问题似乎与这个类似,但有一个区别:我希望我的脚本最终自动删除文件夹,而不是手动删除。 - maxischl
6个回答

14

这会递归地删除当前目录下的所有*.pyc文件和pycache目录:

  • 使用Python:
import os

os.popen('find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf')
  • 或者手动使用终端或命令提示符:
find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

1
它运行良好。干得好! - Lixt

6

稍微有些偏离主题,如果你不想要字节码缓存,最好的解决方案是首先不要生成它们。如果每次运行后总是删除它们,那么它们就毫无用处。可以采取以下两种方式:

  1. 使用 -B 选项调用 python/python3(仅影响当前启动),或者...
  2. 设置 PYTHONDONTWRITEBYTECODE 环境变量以影响所有 Python 启动,直到取消设置,例如在 bash 中,输入 export PYTHONDONTWRITEBYTECODE=1

这需要在启动 Python 脚本之前进行设置,因此最好使用简单的 bash 脚本等来包装你的脚本,并在其中设置相应的开关/环境。


谢谢您的建议,但那不是一个选项。我会把模拟器发送给其他人,我不希望那个人做出任何大的更改。 - maxischl
1
@maxischl:这就是为什么我建议使用包装脚本;一个三行(或更少)的包装脚本可以消除手动调整的需要。 - ShadowRanger
我认为你所建议的是正确而稳健的解决方案,但在这种情况下,我宁愿坚持快速而粗略的版本。 - maxischl

3

如果您可以访问命令行界面和find实用程序,则还有另一种简单的解决方案:

find . -type d -name __pycache__

如您以通俗易懂的语言提问,它将在当前文件夹 (.) 中查找与您的模式 -name __pycache__ 完全匹配的目录(-type d)。您可以使用这个命令来确定这些文件夹的位置,并且删除它们:

find . -type d -name __pycache__ -exec rm -fr {} \;

这种解决方案的巨大优势在于它能够轻松地转移到其他任务(比如查找*.pyc文件?)并成为了我日常使用的工具。


2

如果您已经知道__pycache__文件夹的位置,那么以下是一个简单的解决方案:

import shutil
import os

def clearCache():
    """
    Removes generic `__pycache__` .

    The `__pycache__` files are automatically created by python during the simulation.
    This function removes the genric files on simulation start and simulation end.
    """
    path = 'C:/Users/Yours/Desktop/LPG'
    try:
       for all in os.listdir(path):
        if os.path.isdir(path + all):
            if all == '__pycache__':
                shutil.rmtree(path + all, ignore_errors=False) 
    except:
        pass
clearCache()

只需要简单地修改路径,即可实际使用你的路径。 如果你想让脚本穿透子目录并删除pycache文件夹,只需检查以下内容。

示例

import shutil
import os

path = 'C:/Users/Yours/Desktop/LPG'
for directories, subfolder, files in os.walk(path):
    if os.path.isdir(directories):
        if directories[::-1][:11][::-1] == '__pycache__':
                        shutil.rmtree(directories)


2
我是否忽略了某些原因,需要使用 directories[::-1][:11][::-1] 而不是仅使用 directories[-11:]directories.endswith() - Wups
你可以使用 endswith() 代替索引和切片。 - Umutambyi Gad

0
如果你想从任何目录中删除任何文件夹,请使用此函数。
默认情况下,它会从当前目录开始递归地进入每个子目录进行删除。
import os
import shutil


def remove_dirs(curr_dir='./', del_dirs=['temp_folder', '__pycache__']):
    for del_dir in del_dirs:
        if del_dir in os.listdir(curr_dir):
            shutil.rmtree(os.path.join(curr_dir, del_dir))

    for dir in os.listdir(curr_dir):
        dir = os.path.join(curr_dir, dir)
        if os.path.isdir(dir):
            self.remove_dirs(dir, del_dirs)

-1
你可以像这样使用osglob
import os, glob

in_dir = "/path/to/your/folder"

pattern = ['__pycache__']

for p in pattern:
    [os.remove(x) for x in glob.iglob(os.path.join(in_dir, "**", p), recursive=True)]

1
这会导致一个 PermissionError: [Errno 1] Operation not permitted: ... 的错误。 - maxischl
在某些特定的时刻,我们会遇到一些错误。尽管它在某些情况下能够正常工作,但有时候会出现IsADirectoryError: [Errno 21] Is a directory: '../game/gui/__pycache__'的错误。 - Lixt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接