Reputation: 47
I'm having a little issue with my code, mainly (I think) with the try/except part. My code will generate a wordlist of the users choice. Here is the code:
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()
If I enter a valid filename on the first attempt, it works as it should. However, if I enter an invalid filename and choose to try again, I get the following error, even if my second attempt is definitely a valid filename:
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
I can't work out why though. Surely, when I select 'y'
, the code just executes from the beginning of the gen_wordlist()
function, and should work the same as if I had entered a valid filename on the first attempt, right?
Upvotes: 1
Views: 1187
Reputation: 1121366
If the open()
call raises a FileNotFoundError
exception, my_file
was never set and all other references trying to use that name will fail.
That includes the code after gen_wordlist()
was called in the exception handler. Sure, the new call may succeed, but that call then returns back to this frame where my_file
was not set.
You want to return here too, instead:
if retry == 'y' or retry == 'Y':
return gen_wordlist()
Otherwise you'll ignore the result of the successful recursive call here too.
It's not a great idea to use recursion to handle errors in user input. Use a loop instead:
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()
This while
loop then runs until my_file
has successfully been set to a file object.
Upvotes: 4
Reputation: 13372
Re-read the error message, it clearly says you have used the variable my_file
before assignment. Now, look at your code, when do you define my_file
in the except
clause? The try
falls out without declaring/assigning to the my_file
variable in case of an error. Rest, Martijn's answer points out some more issues.
Upvotes: 0