在shutil.copy

时间:2019-07-17 20:22:37

标签: python shutil

我有以下代码,因为有时这些文件是相同的,有时却是相同的。

import shutil
try:
   shutil.copy('filea','fileb')
   shutil.copy('filec','filed')
except shutil.SameFileError
   pass

问题在于,如果第一个副本具有相同的文件,则第二个副本将不会发生。

有关如何解决此问题的任何建议?我没有在shutil documentation中看到禁用此检查的参数。

3 个答案:

答案 0 :(得分:0)

尝试shutil.copyfile。 docs状态:如果dst已经存在,它将被替换。

这应该满足您的需求,除非我误解了您的问题。


另一种方法是使用shutil.move,然后在需要保留副本的情况下将文件复制回源目录。

根据文档:如果目标位置已经存在但不是目录,则可能会根据os.rename()语义将其覆盖。

答案 1 :(得分:0)

您可以仅分隔复制呼叫:

try:
   shutil.copy('filea','fileb')
except shutil.SameFileError:
   pass

try:
   shutil.copy('filec','filed')
except shutil.SameFileError:
   pass

或将这四行放在一个函数中。

答案 2 :(得分:0)

对此有一个不太优雅的解决方案。我真的不推荐这个解决方案。但这取决于你:)

shutil._samefile 函数检查源文件和目标文件是否相同(它将始终被调用,因此副本没有任何停用它的选项)。如果返回值为 True(因此文件相同),则会引发 SameFileError 异常(如下所示)。

if _samefile(src, dst):
    raise SameFileError("{!r} and {!r} are the same file".format(src, dst))

您可以强制 _samefile 函数在任何情况下都返回 False

import shutil


def my_same_file_diff_checker(*args, **kwargs):
    return False


shutil._samefile = my_same_file_diff_checker


shutil.copy("test.ini", "test.ini")

重要提示:

使用此解决方案不会引发 SameFileError,但会运行复制功能的其他部分。这意味着例如。文件的时间戳将被更新。如下图所示,file 的内容将被重写到 file 中。

with open(src, 'rb') as fsrc:
    with open(dst, 'wb') as fdst:
        copyfileobj(fsrc, fdst)

其他(也许更优雅的)解决方案:

  • 我建议使用 2 个分隔的 try-except(如 @hko 所写)
  • 在复制之前检查文件的路径(可能是大多数 Pythonic 解决方案)。
  • 编写自己的复制函数/方法