python try / except / else with recursion

时间:2016-08-20 23:24:42

标签: python recursion try-except

Python版本:2.7。操作系统:Windows 10 64位。

注意:我找到了解决下面描述的不使用try / except / else语句的问题的方法。我问下面的问题只是因为我很好奇为什么代码的行为方式,如果有办法用try / except / else做我想做的事。

我有一个名为blah.py的文件,其代码如下:

import os

def makeFolder(dirName, num = 0):
    try:
        os.mkdir(dirName + '_' + str(num)) #error if argument of os.mkdir already exists
    except:
        makeFolder(dirName, num = num + 1)
    else:
        return dirName + '_' + str(num)

现在我转到Powershell,输入:

import blah
myStr = blah.makeFolder('myFolder')
print myStr
print type(myStr)

它可以实现我的期望 - 创建一个名为myFolder_0的文件夹,并打印myFolder_0<type 'str'>。现在,仍然在Powershell中,我输入:

myStr1 = blah.makeFolder('myFolder')
print myStr1
print type(myStr1)

这次我按照预期创建了一个名为myFolder_1的文件夹,但不是打印myFolder_1<type 'str'>,而是打印None<type 'NoneType'>。我将在以后每次使用blah.makeFolder('myFolder')时继续这样做。

如果我将我在Powershell中输入的命令放在脚本中,行为也会异常不同。我创建了一个名为blah2.py的文件,它与blah.py相同,但最后有一个脚本:

import os

def makeFolder(dirName, num = 0):
    try:
        os.mkdir(dirName + '_' + str(num)) #error if argument of os.mkdir already exists
    except:
        makeFolder(dirName, num = num + 1)
    else:
        return dirName + '_' + str(num)

myStr = makeFolder('myFolder')
print myStr
print type(myStr)

myStr1 = makeFolder('myFolder')
print myStr1
print type(myStr1)

然后在Powershell:

python blah2.py

这次它使myFolder_0打印myFolder_0<type 'str'>,(因此myStr块的工作方式与blah.py一样),然后进入无限递归(所以myStr1块不起作用)。因此,由于我不理解的原因,行为与交互式会话期间的行为不同。如果我再次输入python blah2.py,它会生成myFolder_1并打印None<type 'NoneType'>myStr块),然后再次进入无限递归(myStr1块)。

为什么脚本的行为与交互式会话的行为不同,为什么脚本中会发生无限递归,还有我的代码版本仍然使用try / except / else,但有效吗?

2 个答案:

答案 0 :(得分:3)

如果我在递归调用中添加return,您的代码可以正常工作:

import os

def makeFolder(dirName, num = 0):
    try:
        os.mkdir(dirName + '_' + str(num))
    except OSError:
        return makeFolder(dirName, num = num + 1)
    else:
        return dirName + '_' + str(num)

print(makeFolder('myFolder')) # myFolder_0
print(makeFolder('myFolder')) # myFolder_1

至于为什么你会看到你所看到的......那里肯定会发生其他事情。您为blah2.py分享的代码无法正常工作,因为blah未在任何地方定义。我的猜测是你在没有意识到的情况下运行不同的代码。 (也许是不同目录中文件的不同副本?)

答案 1 :(得分:0)

我首先想到的是,您所看到的不一致行为可能是因为如果您依次运行某些目录,则这些目录已经存在。要防止这种情况,请尝试将此代码添加到开头,以清理上一次运行创建的任何目录:

import os

for dirname in [f for f in os.listdir('.') if 
                (os.path.isdir(f) and f.startswith('myFolder'))]:
     os.rmdir(dirname)

但是,如何解决实际问题:

import os

def makeFolder(dirName, num = 0):
    try:
        os.mkdir(dirName + '_' + str(num)) #error if argument of os.mkdir already exists
    except:
        return makeFolder(dirName, num = num + 1)
    else:
        return dirName + '_' + str(num)