简体   繁体   中英

try/except issue statement in python 3

Hello I am new to Python and learning basics. I am curious to understand try/except statements in Python and I want to ask whether I should keep as little as possible in try block/portion as mentioned below (Please refer Following Code Working Properly) or try to keep as much in try block/portion (Please refer Following Code Not Working Properly When I Enter Any String but it works when I enter float/integer).

So, these are the two scenarios almost the same but the other code (in which I am keeping minimum code) is giving me an error when I enter a string.

Why is that doing it? What should I do in that case if I want to keep as little as possible in try/except blocks? Any leads would be highly appreciated. What's the alternate correct solution of my second code in which I am keeping minimum lines of code? - What adjustment I am supposed to make in it to work for me? Please help.

NameError: name 'fahr' is not defined
***# Following Code Working Properly:***
inp = input('Enter Fahrenheit Temperature:')
try:
    fahr = float(inp)
    cel = (fahr - 32.0) * 5.0 / 9.0
    print(cel)
except:
    print('Please enter a number')
***# Following Code Not Working Properly:***
inp = input('Enter Fahrenheit Temperature:')

try:
    fahr = float(inp)
except:
    print('Please enter a number')

fahr = float(inp) # Even if I comment it, it doesn't make any difference when it comes to entering float in an input but it raises red flag if I enter string.
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)

Less in the try expression is preferable

It is preferable that the code you enter the try: block should only contains the bits that may directly produce the error in interest. This way, it would be easier to track its source and not to get distracted by any surrounding and presumably safe code.

In doing so, think about control flow

The first snippet of code runs correctly because when the error is raised in line 4, the control flow jumps directly to the except block, so any statements that depend on the fahr variable do not get affected. However, in the second snippet, if the error is raised and the control flow jumps to the except block, the fahr variable does not get defined, making the subsequent statements that depend on it raise the NameError error that you talk about. A safer method is to define an alternate, default fahr = 0 for example in the except block or to use an else: block, where the control flow jumps to if no errors are raised in the try: block.

Make your error handling specific

Always try and make the error you anticipate may be raised explicit in your code. this is by putting the base class of the group of errors after the except keyword and before the colon. For example,

except ValueError:

First, do not use a general catch clause. This would be considered bad practice.

In your case, it would make sense to catch ValueErrors in case a user enters letters instead of numbers in example:

while True:
    inp = input('Enter Fahrenheit Temperature:')
    try:
        fahr = float(inp)
        break # Break loop to get to main program
    except ValueError:
        print('Please enter a number')

fahr = float(inp) # Even if I comment it, it doesn't make any difference when it comes to entering float in an input but it raises red flag if I enter string.
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)

One alternative would be a recursive input if you really want to avoid the loop:

def force_input(prompt):
    inp = input(prompt)
    try:
        fahr = float(inp)
        return fahr
    except ValueError:
        print('Please enter a number')
        force_input(prompt)
        return False

fahr = force_input("Enter Fahrenheit Temperature:")
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)

Your first set of code is fine, but it doesn't recover from the error. If you'd like the program to gracefully recover and ask again for an input, you'll need to continually loop the input and try until it passes, like such.

while True:
    inp = input('Enter Fahrenheit Temperature:')
    try:
        fahr = float(inp)
        break
    except:
        print('Please enter a number')

fahr = float(inp) # Even if I comment it, it doesn't make any difference when it comes to entering float in an input but it raises red flag if I enter string.
cel = (fahr - 32.0) * 5.0 / 9.0
print(cel)

Your problem is quite simple: try: except: is not a loop.

try:
    fahr = float(inp)
except:
    print('Please enter a number')

Here, you try to set fahr, and if you fail, you print 'Please enter a number' and your program continues.

But it failed to set fahr, So on the next line, when you try to use fahr to run calculation. it does not exist, Hence, NameError: name 'fahr' is not defined .

Why does this work:

inp = input('Enter Fahrenheit Temperature:')
try:
    fahr = float(inp)
    cel = (fahr - 32.0) * 5.0 / 9.0
    print(cel)
except:
    print('Please enter a number')

Here, you try to set fahr, you run your calculation, you print. But if any of these steps fail, you print your error and continue.

See the difference? I hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM