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

时间:2016-04-22 14:15:02

标签: python execution

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

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链接中显然有用的内容,但我无法让代码工作。似乎行os.rename(path, target)之前正在执行path = os.path.join(directory, filename)行!

提前感谢您的帮助,经过四个小时的谷歌后我不知道该怎么办。

2 个答案:

答案 0 :(得分:3)

您发布的代码不会抛出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)

答案 1 :(得分:1)

查看问题的标记源,您似乎正在为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,并且您定义{{ 1}}在开始时,当Python命中第一个path = "Nothing"时,它仍将具有该值。

要解决此问题,只需将所有缩进转换为制表符或空格(使用的缩写为question of taste)。大多数文本编辑器会为你做这个,如果只是缩进然后去除所有东西(即按Ctrl-A,Tab,Shift-Tab)。