Python重命名文件很奇怪

Python重命名文件很奇怪,python,python-3.x,Python,Python 3.x,我有这个功能: def rename(path): """ Renames all the files to be cropped-%d.xxx """ count = 0 for thing in os.listdir(path): root, ext = os.path.splitext(thing) os.rename(os.path.join(path, thing), os.path.join(path, sys.argv[1]+

我有这个功能:

def rename(path):
    """ Renames all the files to be cropped-%d.xxx """
    count = 0
    for thing in os.listdir(path):
        root, ext = os.path.splitext(thing)
        os.rename(os.path.join(path, thing), os.path.join(path, sys.argv[1]+".cropped{0}".format(count)+ext))
        count += 1

这是可行的,但如果我在已经运行它的目录上运行它,它似乎会删除其重命名的一半文件。为什么会发生这种情况?

当具有新名称的文件已经存在时,就会发生这种情况,因此您正在用重命名的文件替换现有文件,并在过程中丢失原始文件。

如果您打印出正在进行的重命名,则更容易看到发生了什么:

def rename(path):
    """ Renames all the files to be cropped-%d.xxx """
    count = 0 
    for thing in os.listdir(path):
        root, ext = os.path.splitext(thing)
        old = os.path.join(path, thing)
        new = os.path.join(path, sys.argv[1] + ".cropped{0}".format(count) + ext)
        print("rename from {} to {}".format(old, new))
        os.rename(old, new)
        count += 1
下面是运行两次的示例输出:

dan@dandesk:~$ python ok.py b
rename from test/4.txt to test/b.cropped0.txt
rename from test/2.txt to test/b.cropped1.txt
rename from test/5.txt to test/b.cropped2.txt
rename from test/7.txt to test/b.cropped3.txt
rename from test/1.txt to test/b.cropped4.txt
rename from test/3.txt to test/b.cropped5.txt
rename from test/6.txt to test/b.cropped6.txt
dan@dandesk:~$ python ok.py b
rename from test/b.cropped3.txt to test/b.cropped0.txt
rename from test/b.cropped4.txt to test/b.cropped1.txt
rename from test/b.cropped2.txt to test/b.cropped2.txt
rename from test/b.cropped5.txt to test/b.cropped3.txt
rename from test/b.cropped1.txt to test/b.cropped4.txt
rename from test/b.cropped0.txt to test/b.cropped5.txt
rename from test/b.cropped6.txt to test/b.cropped6.txt
下面是测试目录的内容:

dan@dandesk:~$ ls -1 test
b.cropped2.txt
b.cropped3.txt
b.cropped4.txt
b.cropped5.txt
b.cropped6.txt
如您所见,
b.crapped1.txt
b.crapped0.txt
已消失。上述输出揭示了原因:

rename from test/b.cropped3.txt to test/b.cropped0.txt
rename from test/b.cropped4.txt to test/b.cropped1.txt
...
rename from test/b.cropped1.txt to test/b.cropped4.txt
rename from test/b.cropped0.txt to test/b.cropped5.txt
我们将两个文件重命名为丢失的名称,然后稍后再次重命名,这意味着我们将丢失
b.crapped4.txt
b.crapped5.txt
中的所有文件

您可以通过确保要使用的新名称不存在来避免这种情况,如果存在,则增加
count
,直到获得不存在的文件:

def rename(path):
    """ Renames all the files to be cropped-%d.xxx """
    count = 0
    for thing in os.listdir(path):
        root, ext = os.path.splitext(thing)
        old = os.path.join(path, thing)
        while True:
            new = os.path.join(path, sys.argv[1] + ".cropped{0}".format(count) + ext)
            if not os.path.exists(new):
                break
            count += 1
        print("rename from {} to {}".format(old, new))
        os.rename(old, new)
        count += 1
输出:

dan@dandesk:~$ python ok.py b
rename from test/4.txt to test/b.cropped0.txt
rename from test/2.txt to test/b.cropped1.txt
rename from test/5.txt to test/b.cropped2.txt
rename from test/1.txt to test/b.cropped3.txt
rename from test/3.txt to test/b.cropped4.txt
rename from test/6.txt to test/b.cropped5.txt
dan@dandesk:~$ python ok.py b
rename from test/b.cropped3.txt to test/b.cropped6.txt
rename from test/b.cropped4.txt to test/b.cropped7.txt
rename from test/b.cropped2.txt to test/b.cropped8.txt
rename from test/b.cropped5.txt to test/b.cropped9.txt
rename from test/b.cropped1.txt to test/b.cropped10.txt
rename from test/b.cropped0.txt to test/b.cropped11.txt

您在代码中的什么地方采取了预防措施,使目录中没有包含您要重命名为的名称的文件?也许您是在现有文件的基础上重命名的。(这不是一个错误;旧文件将被删除。)啊,是的,就是这样。现在如何做一个整洁的检查。我可以做一个if-in,检查这个名字是否存在,我想。+1表示认真彻底的回答,尽管它基本上说了我说的话,但我说了之后;)