Python 2.7.11 os.rename 问题和奇怪的执行顺序

Python 2.7.11 os.rename issues and weird execution order

我正在尝试编写一个简单的脚本来检查文件名中是否包含数字,如果有则将其删除。这是我的代码:

import os

directory = raw_input("Enter a path string: ")
print "This will now delete all numbers from the files in %s." %directory

for filename in os.listdir(directory):
    print filename
    for s in filename:
        if s.isdigit():
            print filename
            path = os.path.join(directory, filename)
            print path
            target = os.path.join(directory, filename.replace(s, ""))
            print target
            os.rename(path, target)

print "Done."

当我 运行 它时,我得到以下错误:

Traceback (most recent call last):
File "EditFilename.py", line 15, in <module>
os.rename(path, target)
NameError: name 'path' is not defined

这很奇怪,因为 path 已明确定义。如果我将 for 循环上方的 path 定义为 path = "Nothing" 那么我会收到此错误:

File "EditFilename.py", line 16, in <module>
os.rename(path, target)
OSError: [Errno 2] No such file or directory

我正在遵循 this link 中显然有效的方法,但我无法使我的代码正常工作。 os.rename(path, target) 行似乎在 path = os.path.join(directory, filename) 行之前执行!

预先感谢您的帮助,经过四个小时 google 我不知道该怎么做。

您发布的代码不会抛出 NameError;确保在编辑 运行 代码之前正确地重新启动 Python。

但是,您确实有其他问题会导致 OSError。您永远不会退出 for s in filename: 循环。所以如果你的文件名中有一个以上的数字,你尝试多次重命名它:

>>> filename = 'hunter42'
>>> for s in filename:
...     if s.isdigit():
...         print 'renaming {} to {}'.format(filename, filename.replace(s, ''))
...
renaming hunter42 to hunter2
renaming hunter42 to hunter4

由于 hunter42 已重命名为 hunter2,您无法再将其重命名为其他名称。

改用 any() function 来测试数字一次,而不是在 for 循环中:

for filename in os.listdir(directory):
    if any(s.isdigit() for s in filename):
        path = os.path.join(directory, filename)
        target = os.path.join(directory, filename.translate(None, '0123456789'))
        os.rename(path, target)

我在这里使用 str.translate() 从文件名中删除数字:

>>> filename.translate(None, '01234567890')
'hunter'

你也可以翻译名字,如果和原来的不一样,重命名:

for filename in os.listdir(directory):
    newname = filename.translate(None, '0123456789')
    if filename != newname:
        path = os.path.join(directory, filename)
        target = os.path.join(directory, newname)
        os.rename(path, target)

查看您问题的标记源,您似乎正在为 Python 缩进混合制表符和空格。不要这样做!这会严重混淆您的 Python 解释器,并导致各行与不同的块相关联。

很难确定你的缩进到底是多少,因为问题中的代码块有额外的缩进,但是,你的 if 块中的前三行缩进了 3 个制表符和 4 个制表符空格,以及以下三行,其中包含 8 个空格、1 个制表符和另外 4 个空格。

因此,您的 Python 解释器看到的可能更像这样:

for s in filename:
    if s.isdigit():
        print filename
        path = os.path.join(directory, filename)
        print path
    target = os.path.join(directory, filename.replace(s, ""))
    print target
    os.rename(path, target)

也就是说,os.rename 总是 执行,即使 path 之前没有在 if 块中定义,并且如果您在开始时定义 path = "Nothing",当 Python 命中第一个 os.rename.

时,它仍将具有该值

要解决此问题,只需将所有缩进转换为制表符或空格(使用有点像 question of taste)。大多数文本编辑器都会为您执行此操作,如果只是缩进然后去除所有内容(即按 Ctrl-A、Tab、Shift-Tab)。