Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Python

Uitzonderingen niet afhandelen in Python

Ik zie veel mensen op de verkeerde manier omgaan met uitzonderingen. Wellicht geldt dit ook voor jou. Komt de volgende situatie je bekend voor?

Je schrijft wat code, maar je weet dat de bibliotheek die je gebruikt een uitzondering kan veroorzaken. Je weet niet meer welke precies. Op dit moment is het verleidelijk om zogenaamde catch-all-blokken te gebruiken en door te gaan met de leuke dingen.

Inhoudsopgave

De slechtste manier om het te doen

Het ergste dat je kunt doen, is een try-behalve-blok maken dat alles vangt. Met alles bedoel ik zoiets als:

try:
    ...
except:
    pass

Catch-all blokken zoals deze zijn slecht omdat:

  1. Je hebt geen idee welke andere uitzonderingen er mogelijk zijn (hierover later meer).
  2. We verbergen de uitzondering door in stilte pass te gebruiken in plaats van de fout te loggen.

Verder zal een lege behalve alles opvangen, inclusief KeyboardInterrupt (controle + c), SystemExit , en zelfs NameErrors ! Dit betekent dat de volgende code niet netjes kan worden gestopt:

from time import sleep

while True:
    try:
        print("Try and stop me")
        sleep(1)
    except:
        print("Don't.. stop.. me now!")

Probeer het gerust. U moet uw terminalvenster sluiten of het Python-proces beëindigen om dit programma te stoppen.

Een iets betere manier om alle uitzonderingen op te vangen

Bij gebruik van except Exception . daarentegen , hoewel het nog steeds een snelle en vuile manier is om te veel uitzonderingen op te vangen, kun je het lopende proces in ieder geval goed stoppen:

from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except Exception:
        print("Ok I'll stop!")

Bij het vangen van Exception je zult SystemExit niet vangen , KeyboardInterrupt en andere dergelijke uitzonderingen. Waarom is dat, vraag je?

Alle uitzonderingen erven van een klasse genaamd BaseException . Volgens de officiële documentatie:“In een try statement met een except clausule die een bepaalde klasse vermeldt, behandelt die clausule ook alle uitzonderingsklassen die van die klasse zijn afgeleid. Een lege except is gelijk aan except BaseException , dus het zal alle mogelijke uitzonderingen opvangen.

Daarentegen is de klasse Exception wordt gedefinieerd als:“Alle ingebouwde, niet-uitgeschakelde uitzonderingen zijn afgeleid van deze klasse. Alle door de gebruiker gedefinieerde uitzonderingen moeten ook van deze klasse worden afgeleid.”

Het wordt nog erger

In het volgende voorbeeld gebruiken we de os-bibliotheek om de huidige werkdirectory op te halen. Mijn vette kleine vingers maakten echter een typfout:

import os
try:
    working_dir = os.getcdw()
    print(working_dir)
except:
    print('error')

Omdat os.getcdw is geen functie in de os-module, er wordt een NameError gegenereerd. In plaats van te falen, zal de uitzonderingsclausule de fout opvangen, 'fout' afdrukken en het programma zal doorgaan ondanks onze flagrante typefout. Helaas is deze niet op te lossen door Exception . te vangen ofwel!

Blijkbaar is ons trucje vanaf stap één geen oplossing voor al onze problemen. Dus wat moet wij doen?

Vang wat je aankunt

Een veel gehoorde uitdrukking over uitzonderingen is:pak wat je aankan . Veel ontwikkelaars komen in de verleiding om uitzonderingen direct af te handelen, terwijl het vaak beter is om de uitzondering te laten verspreiden naar een deel van je programma dat het daadwerkelijk aankan.

Denk bijvoorbeeld aan het deel van een teksteditor dat bestanden opent en laadt, laten we het de OpenFile noemen. klas. Als de gebruiker heeft gevraagd om een ​​bestand te openen dat niet bestaat, kun je die fout direct afhandelen of laten verspreiden.

In dit geval is het beter om de uitzondering door te geven aan de beller, omdat OpenFile heeft geen idee hoe erg deze uitzondering is voor de beller. De beller kan de situatie op meerdere manieren afhandelen:

  • Het zou in plaats daarvan een nieuw bestand met die naam kunnen maken en doorgaan
  • Misschien heeft de beller het bestand daar nodig, in welk geval het een foutdialoogvenster kan tonen om de gebruiker te informeren dat dit bestand niet bestaat.

Hoe dan ook, het is niet de OpenFile klas om te beslissen wat te doen in het geval van een FileNotFoundError .

Moet er dan altijd een uitzondering worden gepropageerd? Nee. Een mogelijke uitzondering die kan worden afgehandeld in de FileOpen-klasse, is de TimeoutError . U kunt het bijvoorbeeld een paar keer opnieuw proberen zonder de beller lastig te vallen met de fout. Dit is een uitzondering die OpenFile aankan, dus het is oké om het te vangen en het opnieuw te proberen.

Conclusie

U mag in geen geval meer uitzonderingen opvangen dan u aankan. Deken behalve blokken zijn een recept voor bugs en onvoorspelbare code. Met andere woorden:vang wat je aankan.

Als je je code schrijft met de 'catch what you can handle'-matra in gedachten, is het schrijven van catch-all-blokken alle regels overtreden. Dus alsjeblieft, stop ermee. Als oefening kunt u een deel van uw bestaande code opnieuw bekijken en kijken of deze met deze nieuwe kennis kan worden verbeterd!


Python

  1. Python-operators
  2. Python-fouten en ingebouwde uitzonderingen
  3. Aangepaste Python-uitzonderingen
  4. Hoe de huidige datum en tijd in Python te krijgen?
  5. Java-vangst Meerdere uitzonderingen
  6. Niet slecht zijn in het aanleren van nieuwe software
  7. Python Print()-instructie:afdrukken met voorbeelden
  8. Python Dictionary Append:Hoe een sleutel/waarde-paar toe te voegen
  9. Python New Line:afdrukken ZONDER nieuwe regel in Python
  10. Python-gemiddelde:hoe het GEMIDDELDE van een lijst in Python te vinden?
  11. Nu aan het werk? Hoe om te gaan met een toestroom van sollicitanten