Python 3尝试除问题

时间:2014-02-26 17:20:42

标签: python python-3.x try-catch except

我的代码存在一些问题,主要是(我认为)与try / except部分有关。我的代码将生成用户选择的词表。这是代码:

def gen_wordlist():
    filename = input("Please enter the name of the wordlist:  ")

    try:
        my_file = open(filename, 'r')

    except FileNotFoundError:
        retry = input("No file named "+filename+". Would you like to try again (y/n)")
        if retry == 'y' or retry == 'Y':
            gen_wordlist()
        else:
            print("Goodbye :-)")
            sys.exit()

    words = my_file.read()
    my_file.close()
    return(words.split())


words = gen_wordlist()

如果我在第一次尝试时输入有效的文件名,它就可以正常工作。但是,如果我输入无效的文件名并选择再次尝试,即使我的第二次尝试肯定是有效的文件名,我也会收到以下错误:

Traceback (most recent call last):
  File "TEST.py", line 20, in <module>
    words = gen_wordlist()
  File "TEST.py", line 15, in gen_wordlist
    words = my_file.read()
UnboundLocalError: local variable 'my_file' referenced before assignment

我无法理解为什么。当然,当我选择'y'时,代码只是从gen_wordlist()函数的开头执行,并且应该像在第一次尝试时输入有效的文件名一样工作,对吗?

2 个答案:

答案 0 :(得分:4)

如果open()调用引发了FileNotFoundError异常,则永远不会设置my_file,并且尝试使用该名称的所有其他引用都将失败。

包含在异常处理程序中调用gen_wordlist()后的代码。当然,新的呼叫可能会成功,但是那个呼叫然后返回回到my_file 而不是设置的那个帧。

你也想回到这里,而不是:

if retry == 'y' or retry == 'Y':
    return gen_wordlist()

否则你也会在这里忽略成功递归调用的结果。

使用递归来处理用户输入中的错误并不是一个好主意。改为使用循环:

my_file = None

while my_file is None:
    filename = input("Please enter the name of the wordlist:  ")

    try:
        my_file = open(filename, 'r')
    except FileNotFoundError:
        retry = input("No file named " + filename + ". Would you like to try again (y/n)")
        if retry.lower() == 'y':
            # back to the top of the loop
            continue

        print("Goodbye :-)")
        sys.exit()

然后运行此while循环,直到my_file成功设置为文件对象。

答案 1 :(得分:0)

重新阅读错误消息,它清楚地表明您在分配之前已使用变量my_file。现在,查看代码,何时在my_file子句中定义except?如果出现错误,try会在没有声明/分配给my_file变量的情况下失败。休息时,Martijn的回答指出了一些问题。