【问题标题】:python try/except/else with recursion [duplicate]带有递归的python try/except/else [重复]
【发布时间】:2016-12-27 19:49:54
【问题描述】:

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,但可以工作?

【问题讨论】:

  • 欢迎来到 StackOverflow!我只想赞扬您提出了一个很好的问题,包括一个很好的紧凑示例。干得好!
  • “Powershell”与这里有什么关系?你是打错了“Python shell”还是你实际上在使用 PowerShell?
  • blah2.py 在我看来不正确...它执行blah.makeFolder,但blah 没有在任何地方定义?
  • 你得到的是非类型,因为当 except 语句被触发时, else 语句不会被触发,所以你没有返回任何东西。并且您的函数没有考虑递归调用的返回
  • 总是处理一个特定的异常,一个空白的except 语句将捕获python中所有可能的异常。这可能会导致很多假设和奇怪的行为:)...except OSError

标签: python recursion try-except


【解决方案1】:

如果我在递归调用中添加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 没有在任何地方定义。我的猜测是你在没有意识到的情况下运行不同的代码。 (可能是不同目录中的文件的不同副本?)

【讨论】:

  • 打败了我 :),他还应该处理适当的异常,即 OSError,而不是有一个 except 来捕获所有可能的异常
  • 太好了,这行得通,谢谢!关于blah2的东西,有两件事:首先,在原始帖子中有一个错字,我的blah2.py文件没有blah.makeFolder,只有makeFolder。我将立即编辑。其次,我重新启动计算机并再次运行它,然后它开始做与交互式会话相同的事情,所以我猜内存中有一些奇怪的东西。
【解决方案2】:

我的第一个想法是,您看到的不一致行为可能是因为某些目录已经存在,如果您一个接一个地运行它们。为防止这种情况,请尝试将此代码添加到开头以清理之前运行创建的所有目录:

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2017-06-26
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多