Python:如何创建一个目录并在必要时覆盖现有目录?

3
我希望创建一个新目录,如果旧目录存在则删除它。我使用以下代码:

if os.path.isdir(dir_name):
    shutil.rmtree(dir_name)
os.makedirs(dir_name)

如果目录不存在,它会正常工作。 如果目录存在并且程序按照正常方式运行,则会出现错误。(WindowsError: [Error 5] Access is denied: 'my_directory') 但是,如果目录已经存在并且在调试模式下逐行执行程序,则也可以正常工作。我猜想shutil.rmtree()和makedirs()的调用之间需要一些时间。 有什么正确的代码可以避免出现错误吗?

我相信你得到这个错误的原因是因为你没有对你尝试删除的目录具有读取权限。要授予权限,请键入chmod +r directory_name,然后你应该就有权限了。 - BrockLee
@PiJoules 这并不能解释为什么调试时它可以工作。 - Raydel Miranda
2个回答

7

在Python中,只有前一个语句执行完毕后,才会执行当前语句。这就是解释器的工作原理。

我猜测shutil.rmtree命令告诉文件系统删除某个目录树,此时Python会终止该语句的工作--即使文件系统尚未完全删除目录树--。因此,如果目录树足够大,在Python到达os.makedirs(dir_name)这一行时,该目录可能仍然存在。

一个比删除更快的操作是重命名目录:

import os
import tempfile
import shutil

dir_name = "test"

if (os.path.exists(dir_name)):
    # `tempfile.mktemp` Returns an absolute pathname of a file that 
    # did not exist at the time the call is made. We pass
    # dir=os.path.dirname(dir_name) here to ensure we will move
    # to the same filesystem. Otherwise, shutil.copy2 will be used
    # internally and the problem remains.
    tmp = tempfile.mktemp(dir=os.path.dirname(dir_name))
    # Rename the dir.
    shutil.move(dir_name, tmp)
    # And delete it.
    shutil.rmtree(tmp)


# At this point, even if tmp is still being deleted,
# there is no name collision.
os.makedirs(dir_name)

我刚刚运行了你的代码几次。它可以正常工作。谢谢。 - Thomas Schreiter
@ThS 很高兴能帮忙,别忘了点赞并标记为已解答。 - Raydel Miranda
我想这么做,但我没有必要的15个声望。 - Thomas Schreiter

-1

这个怎么样?

import shutil
import os

dir = '/path/to/directory'
if not os.path.exists(dir):
    os.makedirs(dir)
else:
    shutil.rmtree(dir)           
    os.makedirs(dir)

这并没有改进OP的代码。也没有解释为什么OP会出现那个错误。此外,你的答案与这个太相似了:https://dev59.com/EGgu5IYBdhLWcg3wASaO - Raydel Miranda
我同意@RaydelMiranda。 - brodegon

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