ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ
try, except, else, finally
Some errors you can see coming: a user types five where you asked for a number. You
don't want the program to stop for that. You want it to say something useful and carry
on. By the end of this lesson you'll handle an error on purpose and know exactly where
your program continues afterwards.
Catching an error
int() can't convert five, so this program stops with a traceback:
age = int(input("Age: "))
print("Next year you'll be", age + 1)In the editor, press Escape then Tab to move on.
One answer per line, given to input() in order.
Put the line that might fail inside try, and say what to do in except:
text = input("Age: ")
try:
age = int(text)
print("Next year you'll be", age + 1)
except ValueError:
print("That's not a whole number.")
print("Done")In the editor, press Escape then Tab to move on.
One answer per line, given to input() in order.
Python runs the
block. If a line in it raises a ValueError, Python jumps to the
block for that type. That's how you
an error, also called catching it. Change the Input to 17 and run it again: the
except block is skipped.
Where does the program go after the except? Predict:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
try:
print("start")
number = int("five")
print("converted")
except ValueError:
print("handled")
print("after")Python prints
start handled after
The error on line 3 ends the try block on the spot, so 'converted' never prints. After the except block, Python carries on after the whole try statement: 'after'.
If you picked the first answer, you pictured Python going back to finish the try
block. It never does: the rest of the try block is skipped, and once the except
block is done, the program continues after the whole statement. The line that failed
never finished, so its assignment never happened. Predict:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
try:
age = int("five")
except ValueError:
print("Not a number")
print(age)Python prints
Not a number
Traceback (most recent call last):
File "<your code>", line 5, in <module>
print(age)
^^^
NameError: name 'age' is not definedint('five') failed, so 'age = ...' never finished and the name age was never made. The except printed its message, then line 5 asked for a name that doesn't exist. If you pictured try as a safe place where age gets some value anyway, this is the surprise.
If age had a value before the try (say age = 0 above it), the last line would
print 0: the name keeps its old value, because the failed assignment never happened.
Always name the error
except: with no type catches every error, including your own typos:
else and finally
A try statement can have two more blocks. Predict the order:
ውጤቱን ገምቱ
Decide before you look. Guessing wrong is how this sticks.
try:
print("start")
int("five")
except ValueError:
print("handled")
else:
print("no error")
finally:
print("finally")
print("after")Python prints
start handled finally after
There was an error, so else is skipped: else runs only when the try block had no error. finally runs either way.
The
block runs only when the try block had no error, like a loop's else, which runs
only when there was no break (lesson 3.3). The
block always runs: with no error, with an error that's handled, and even with one no
except catches, where it runs just before the program stops with the traceback. It's
for cleaning up, like closing a file (lesson 8.1).
Why not put "no error" code at the end of the try block? An error there would be
caught by an except meant for something else. else keeps try to the line that
might fail.
ጥያቄ
When does the else of a try run?
Validation done right
Lessons 3.5 and 5.8 checked text with isdigit() before converting. That's wrong in
both directions. It turns away text int() accepts:
print(int(" 5 "), int("-5"))
print(" 5 ".isdigit(), "-5".isdigit())In the editor, press Escape then Tab to move on.
And it lets through ፩, which int() can't convert (lesson 6.3), so 5.8's
ask_number still stops with a ValueError if someone types it. The honest test is to
try int() itself. Here's ask_number from lesson 5.8, rewritten
with try. With isdigit(), it could never accept a temperature of -3:
def ask_number(prompt, low, high):
while True:
text = input(prompt)
try:
number = int(text)
except ValueError:
number = None
if number is not None and low <= number <= high:
return number
print(f"Please enter a number from {low} to {high}.")
print(ask_number("Temperature: ", -10, 45))In the editor, press Escape then Tab to move on.
One answer per line, given to input() in order.
There are names for the two styles.
,
"easier to ask forgiveness than permission", tries and handles the error.
,
"look before you leap", checks first. For conversions, EAFP is usually right: int()
knows exactly what it accepts. LBYL is fine for simple checks, like if key in prices.
An error raised inside a function can be caught by the code that called it. to_age
doesn't catch it, so it goes up to the global code, which does:
Caught by the caller
Press Next to run one line at a time. Each arrow shows the object a name refers to. Each call gets its own frame of names, below the frame that called it.Each row is one step: the line that just ran, and the object each name refers to after it, frame by frame, oldest first.
Frames, oldest first: global.
Step 1 of 7
Step 1 of 7. Line 1: def to_age(text):. Nothing in memory changed.
| Step | Line | Names and objects |
|---|---|---|
| 1 | 1 |
|
| 2 | 4 |
|
| 3 | 5 |
|
| 4 | 2 |
|
| 5 | 5 |
|
| 6 | 6 |
|
| 7 | 7 |
|
መልመጃ
A safe to_int
Write to_int(text): return the whole number in text, or None if int() can't
convert it. repr (lesson 6.1) shows each test's quotes and spaces.
'42' -> 42
' 5 ' -> 5
'-5' -> -5
'5.5' -> None
'' -> None
'፩' -> NoneYour code
def to_int(text):
# Try int(text); return None if it raises ValueError
pass
for text in ["42", " 5 ", "-5", "5.5", "", "፩"]:
print(repr(text), "->", to_int(text))In the editor, press Escape then Tab to move on.
መፍትሄውን አሳይHide the solution
This is one way to solve it, not the only one. If yours prints the same thing, it works.
def to_int(text):
try:
return int(text)
except ValueError:
return None
for text in ["42", " 5 ", "-5", "5.5", "", "፩"]:
print(repr(text), "->", to_int(text))ዋና ዋና ነጥቦች
try/except ValueError:handles an error you expect; the program continues after the wholetrystatement.- The rest of the
tryblock is skipped, and an assignment that failed never happened. - Always name the error type: a bare
except:hides your own bugs. elseruns only when there was no error;finallyalways runs.- EAFP (try it) suits conversions; LBYL (check first) suits simple checks. An error from a function can be caught by its caller.