当旧名称与Python3中的新名称冲突时重命名文件集

时间:2017-08-05 04:26:56

标签: python python-3.x rename filenames pathlib

假设我有set个文件重命名操作:

renames={(current_1,new_1),(current_2,new_2),...}

保证文件current_1,current_2,...存在,新文件new_1,new_2,...是唯一的。 所有文件都是pathlib.Path的实例。

但是,它们可能是当前命名为另一个文件的文件必须重命名:即它可能存在current_i==new_j的实例。

实现重命名操作的优雅方法是什么?请注意,我不能迭代renames并重命名每个文件,因为我必须为新名称与尚未重命名的文件名冲突的情况做好准备。

我特意在Python3中寻找一个实现,我希望重命名在上面的表单中保持set

一种简单的方法是临时为文件添加前缀:

temporal_prefix="a big string guaranteed not to appear in file names"
for current,new in renames:
    current.rename(current.with_name(temporal_prefix+current.name))
for current,new in renames:
    current.with_name(temporal_prefix+current.name).rename(new)

但这不是很优雅,它需要最多两倍的所需文件操作。找到一个好的前缀可能本身就是一个问题。 是否可以使用最少数量的文件操作在一个循环中执行此操作?

1 个答案:

答案 0 :(得分:1)

尝试过于聪明并没有多大意义,因为重命名不是一个昂贵的操作,而且当文件存在时你得到的错误非常清楚,可以被困住和处理。您甚至可以先测试每个文件是否存在,如果您愿意,可以避免陷入错误,但如果您认为大多数文件都没有问题,那么可能是浪费时间

只需使用像队列这样的数据结构来保存您的重命名,从头到尾开始处理它们,并在发现由于存在而导致的失败时,将重命名放回到队列的末尾,这样您的循环就会转到它稍后再试。大多数重命名可能会第一次成功,那些不会第二次成功

我没有发布任何示例代码,因为我在生活中从未触及python(抱歉)。在伪代码中我会:

While(renameQueue.hasItems)
  to_rename = renameQueue.dequeue()
  Try
    File.Rename(to_rename.oldName, to-rename.newName)
  OnError FILE_EXISTS
    new_name = system.getRandomTempFilename()
    File.Rename(to_rename.oldName, new_name)
    to_rename.oldName = new_name
    renameQueue.enqueue(to_rename)
  End Try
End While