Kivételek emelése

Befejeződött

Most, hogy már jól ismeri a nyomkövetést és a kivételek kezelését, vegyük át a kivételek emelését.

Lehet, hogy már tud olyan helyzetről, amely hibaállapotot okozhat a kód írásakor. Ilyen helyzetekben hasznos lehet olyan kivételeket emelni, amelyek lehetővé teszik más kódok számára a probléma azonosítását.

A kivételek emelése más kóddal kapcsolatos döntéshozatalban is segíthet. Ahogy korábban láttuk, a hiba függvényében a kód intelligens döntéseket hozhat egy probléma megoldásához, megkerüléséhez vagy figyelmen kívül hagyásához.

Az űrhajósok napi 11 liter vízhasználatra korlátozzák vízhasználatukat. Hozzunk létre egy függvényt, amely az űrhajósok számától függően kiszámítja, hogy mennyi víz marad egy nap vagy több után:

def water_left(astronauts, water_left, days_left):
    daily_usage = astronauts * 11
    total_usage = daily_usage * days_left
    total_water_left = water_left - total_usage
    return f"Total water left after {days_left} days is: {total_water_left} liters"

Próbálja ki öt űrhajós, 100 liter víz maradt, és két nap, hogy menjen:

water_left(5, 100, 2)
'Total water left after 2 days is: -10 liters'

Ez nem túl hasznos, mert a literhiánynak hiba kell lennie. Ezután a navigációs rendszer figyelmeztetheti az űrhajósokat, hogy két nap alatt nem lesz elég víz mindenki számára. Ha Ön mérnök, aki a navigációs rendszert programozási, kivételt jelenthet a függvényben a water_left() hibaállapot riasztásához:

def water_left(astronauts, water_left, days_left):
    daily_usage = astronauts * 11
    total_usage = daily_usage * days_left
    total_water_left = water_left - total_usage
    if total_water_left < 0:
        raise RuntimeError(f"There is not enough water for {astronauts} astronauts after {days_left} days!")
    return f"Total water left after {days_left} days is: {total_water_left} liters"

Most futtassa újra:

water_left(5, 100, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in water_left
RuntimeError: There is not enough water for 5 astronauts after 2 days!

A navigációs rendszerben a riasztás jelzésére szolgáló kód mostantól a riasztáshoz használható RuntimeError :

try:
    water_left(5, 100, 2)
except RuntimeError as err:
    alert_navigation_system(err)

A water_left() függvény frissíthető is, hogy megakadályozza a nem támogatott típusok átadását. A hibakimenet ellenőrzéséhez próbáljon meg olyan argumentumokat átadni, amelyek nem egész számok:

water_left("3", "200", None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in water_left
TypeError: can't multiply sequence by non-int of type 'NoneType'

A hiba TypeError nem túl barátságos abban a kontextusban, amit a függvény elvár. Frissítse a függvényt úgy, hogy használja TypeError , de egy jobb üzenettel:

def water_left(astronauts, water_left, days_left):
    for argument in [astronauts, water_left, days_left]:
        try:
            # If argument is an int, the following operation will work
            argument / 10
        except TypeError:
            # TypeError will be raised only if it isn't the right type 
            # Raise the same exception but with a better error message
            raise TypeError(f"All arguments must be of type int, but received: '{argument}'")
    daily_usage = astronauts * 11
    total_usage = daily_usage * days_left
    total_water_left = water_left - total_usage
    if total_water_left < 0:
        raise RuntimeError(f"There is not enough water for {astronauts} astronauts after {days_left} days!")
    return f"Total water left after {days_left} days is: {total_water_left} liters"

Most próbálkozzon újra a jobb hiba érdekében:

water_left("3", "200", None)
Traceback (most recent call last):
  File "<stdin>", line 5, in water_left
TypeError: unsupported operand type(s) for /: 'str' and 'int'

During handling of the preceding exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in water_left
TypeError: All arguments must be of type int, but received: '3'