Python try-anders

Wat is het beoogde gebruik van de optionele elseclausule van de tryverklaring?


1, Autoriteit 100%

De uitspraken in de elseBlock worden uitgevoerd als de uitvoering van de onderkant van de try– als er geen uitzondering was. Eerlijk gezegd heb ik nog nooit een behoefte gevonden.

Echter, Handling uitzonderingen Opmerkingen:

Het gebruik van de else clausule is beter
dan aanvullende code toevoegen aan het proberen
clausule omdat het per ongeluk vermijdt
Een uitzondering vangen die dat niet was
opgevoed door de code die wordt beschermd door
de try … behalve statement.

Dus, als u een methode hebt die bijvoorbeeld een IOErrorkan gooien, en u uitzonderingen wilt vangen, verhoogt het, maar er is iets anders dat u wilt doen als de eerste operatie slaagt, En u wil niet een IoError van die operatie vangen, u kunt zoiets schrijven:

try:
    operation_that_can_throw_ioerror()
except IOError:
    handle_the_exception_somehow()
else:
    # we don't want to catch the IOError if it's raised
    another_operation_that_can_throw_ioerror()
finally:
    something_we_always_need_to_do()

Als u another_operation_that_can_throw_ioerror()na operation_that_can_throw_ioerror, zou de exceptde fouten van de tweede oproep krijgen. En als je het na de hele tryBlock, zal het altijd worden uitgevoerd, en pas na de finally. De elseHiermee kunt u ervoor zorgen

  1. De tweede operatie is alleen uitgevoerd als er geen uitzondering is,
  2. Het wordt uitgevoerd vóór de finallyblok en
  3. elke IOErrors it raises worden hier niet gepakt

2, Autoriteit 13%

Er is één groot reden om else– stijl en leesbaarheid te gebruiken. Het is over het algemeen een goed idee om de code te behouden die uitzonderingen kan veroorzaken in de buurt van de code die zich bezighoudt met hen. Vergelijk deze bijvoorbeeld:

try:
    from EasyDialogs import AskPassword
    # 20 other lines
    getpass = AskPassword
except ImportError:
    getpass = default_getpass

en

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
else:
    # 20 other lines
    getpass = AskPassword

De tweede is goed wanneer de exceptniet vroeg kan terugkeren, of de uitzondering opnieuw gooien. Indien mogelijk zou ik geschreven hebben:

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
    return False  # or throw Exception('something more descriptive')
# 20 other lines
getpass = AskPassword

Opmerking: Antwoord gekopieerd van recent geplaatst duplicaat Hier , vandaar al deze” askpassword “-spullen.


3, Autoriteit 6%

Eén gebruik: test een code die een uitzondering zou moeten verhogen.

try:
    this_should_raise_TypeError()
except TypeError:
    pass
except:
    assert False, "Raised the wrong exception type"
else:
    assert False, "Didn't raise any exception"

(Deze code moet in de praktijk worden geabstraheerd tot een meer generieke test.)


Antwoord 4, autoriteit 6%

Python proberen-anders

Wat is het beoogde gebruik van de optionele else-clausule van de try-instructie?

Het beoogde gebruik is om een context te hebben waarin meer code kan worden uitgevoerd als er geen uitzonderingen waren waar verwacht werd dat deze verwerkt zouden worden.

Deze context voorkomt dat per ongeluk fouten worden verwerkt die u niet had verwacht.

Maar het is belangrijk om de precieze voorwaarden te begrijpen die ervoor zorgen dat de else-clausule wordt uitgevoerd, omdat return, continueen breakde controlestroom naar else.

Samenvattend

De else-instructie wordt uitgevoerd als er geenuitzonderingen zijn en indien niet onderbroken door een return, continue, of break-statement.

De andere antwoorden missen dat laatste deel.

Uit de documenten:

De optionele else-clausule wordt uitgevoerd als en wanneer de besturing uit de . stroomt
einde
van de try-clausule.*

(Vet toegevoegd.) En de voetnoot luidt:

*Momenteel “vloeit de besturing van het einde”, behalve in het geval van een
uitzondering of de uitvoering van een return-, continue– of break-instructie.

Er is ten minste één voorafgaande uitzonderingsclausule vereist (zie de grammatica). Het is dus echt niet “try-else”, het is “try-except-else(-finally)”, waarbij de else(en finally) optioneel is.

De Python-zelfstudiegaat dieper in op het beoogde gebruik:

De instructie try … behalve heeft een optionele else-clausule, die, wanneer
aanwezig, moet alle behalve clausules volgen. Het is handig voor code die:
moet worden uitgevoerd als de try-clausule geen uitzondering veroorzaakt. Voor
voorbeeld:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

Het gebruik van de else-clausule is beter dan het toevoegen van extra code aan
de try-clausule omdat het voorkomt dat er per ongeluk een uitzondering wordt opgevangen
die niet werd gegenereerd door de code die werd beschermd door de try … behalve
verklaring.

Voorbeeld van onderscheid tussen elseen code na het try-blok

Als je een fout afhandelt, wordt het blok elseniet uitgevoerd. Bijvoorbeeld:

def handle_error():
    try:
        raise RuntimeError('oops!')
    except RuntimeError as error:
        print('handled a RuntimeError, no big deal.')
    else:
        print('if this prints, we had no error!') # won't print!
    print('And now we have left the try block!')  # will print!

En nu,

>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!

Antwoord 5, autoriteit 3%

Try-behalve-else is geweldig voor het combineren van het EAFP-patroonmet eenden typen:

try:
  cs = x.cleanupSet
except AttributeError:
  pass
else:
  for v in cs:
    v.cleanup()

Je zou kunnen denken dat deze naïeve code in orde is:

try:
  for v in x.cleanupSet:
    v.clenaup()
except AttributeError:
  pass

Dit is een geweldige manier om per ongeluk ernstige bugs in uw code te verbergen. Ik heb daar opruimen getypt, maar de AttributeError die me zou laten weten, wordt ingeslikt. Erger nog, wat als ik het correct had geschreven, maar de opschoningsmethode af en toe een gebruikerstype werd doorgegeven met een verkeerd benoemd attribuut, waardoor het halverwege stilletjes faalde en een bestand niet werd afgesloten? Veel succes met het debuggen daarvan.


Antwoord 6, autoriteit 2%

Ik vind het erg handig als je iets moet opruimen, zelfs als er een uitzondering is:

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()

Antwoord 7

Er is een mooi voorbeeld van try-elsein Pep 380 . Kortom, het komt neer op het doen van verschillende uitzonderingsafhandeling in verschillende delen van het algoritme.

Het is zoiets:

try:
    do_init_stuff()
except:
    handle_init_suff_execption()
else:
    try:
        do_middle_stuff()
    except:
        handle_middle_stuff_exception()

Hiermee kunt u de uitzonderingsbehandelingscode dichter bij waar de uitzondering optreedt.


8

Hoewel u er nu geen gebruik van kunt bedenken, kunt u er inzetten dat er een gebruik voor moet zijn. Hier is een unimaginatief monster:

met else:

a = [1,2,3]
try:
    something = a[2]
except:
    print "out of bounds"
else:
    print something

zonder else:

try:
    something = a[2]
except:
    print "out of bounds"
if "something" in locals():
    print something

Hier heb je de variabele somethinggedefinieerd als er geen fout wordt gegooid. U kunt dit buiten de tryblokkeren, maar dan vereist het wat rommelige detectie als een variabele is gedefinieerd.


9

van fouten en uitzonderingen # hanteren uitzonderingen – docs.python.org

De try ... exceptverklaring heeft een optionele elseclausule, die,
Wanneer aanwezig, moet u alle behalve clausules volgen. Het is handig voor code
Dat moet worden uitgevoerd als de try-clausule geen uitzondering oplevert.
Bijvoorbeeld:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

Het gebruik van de else-clausule is beter dan het toevoegen van extra code aan
de try-clausule omdat het voorkomt dat er per ongeluk een uitzondering wordt opgevangen
die niet werd opgewekt door de code die werd beschermd door de try … behalve
verklaring.


Antwoord 10

Dat is het. Het ‘els’-blok van een try-behalve-clausule bestaat voor code die wordt uitgevoerd wanneer (en alleen wanneer) de geprobeerde bewerking slaagt. Het kan worden gebruikt en het kan worden misbruikt.

try:
    fp= open("configuration_file", "rb")
except EnvironmentError:
    confdata= '' # it's ok if the file can't be opened
else:
    confdata= fp.read()
    fp.close()
# your code continues here
# working with (possibly empty) confdata

Persoonlijk vind ik het leuk en gebruik het waar nodig. Het groepeert semantisch uitspraken.


Antwoord 11

try:
    statements # statements that can raise exceptions
except:
    statements # statements that will be executed to handle exceptions
else:
    statements # statements that will be executed if there is no exception

Voorbeeld:

try:
    age=int(input('Enter your age: '))
except:
    print ('You have entered an invalid value.')
else:
    if age <= 21:
        print('You are not allowed to enter, you are too young.')
    else:
        print('Welcome, you are old enough.')

De uitvoer:

>>> 
Enter your age: a
You have entered an invalid value.
>>> RESTART
>>> 
Enter your age: 25
Welcome, you are old enough.
>>>RESTART
>>> 
Enter your age: 13
You are not allowed to enter, you are too young.
>>>

Gekopieerd van: https://geek-university.com /python/the-try-behalve-else-statements/


Antwoord 12

Misschien is een gebruik:

#debug = []
def debuglog(text, obj=None):
    " Simple little logger. "
    try:
        debug   # does global exist?
    except NameError:
        pass    # if not, don't even bother displaying
    except:
        print('Unknown cause. Debug debuglog().')
    else:
        # debug does exist.
        # Now test if you want to log this debug message
        # from caller "obj"
        try:
            if obj in debug:
                print(text)     # stdout
        except TypeError:
            print('The global "debug" flag should be an iterable.')
        except:
            print('Unknown cause. Debug debuglog().')
def myfunc():
    debuglog('Made it to myfunc()', myfunc)
debug = [myfunc,]
myfunc()

Misschien zal dit ook voor jou nuttig zijn.


Antwoord 13

Ik heb de constructie try: ... else:nuttig gevonden in de situatie waarin u databasequery’s uitvoert en de resultaten van die query’s in een aparte database van dezelfde smaak/type logt. Laten we zeggen dat ik veel werkthreads heb die allemaal databasequery’s afhandelen die in een wachtrij zijn geplaatst

#in a long running loop
try:
    query = queue.get()
    conn = connect_to_db(<main db>)
    curs = conn.cursor()
    try:
        curs.execute("<some query on user input that may fail even if sanitized">)
    except DBError:
        logconn = connect_to_db(<logging db>)
        logcurs = logconn.cursor()
        logcurs.execute("<update in DB log with record of failed query")
        logcurs.close()
        logconn.close()
    else:
        #we can't put this in main try block because an error connecting
        #to the logging DB would be indistinguishable from an error in 
        #the mainquery 
        #We can't put this after the whole try: except: finally: block
        #because then we don't know if the query was successful or not
        logconn = connect_to_db(<logging db>)
        logcurs = logconn.cursor()
        logcurs.execute("<update in DB log with record of successful query")
        logcurs.close()
        logconn.close()
        #do something in response to successful query
except DBError:
    #This DBError is because of a problem with the logging database, but 
    #we can't let that crash the whole thread over what might be a
    #temporary network glitch
finally:
    curs.close()
    conn.close()
    #other cleanup if necessary like telling the queue the task is finished

Als u onderscheid kunt maken tussen de mogelijke uitzonderingen die kunnen worden gegenereerd, hoeft u dit natuurlijk niet te gebruiken, maar als code die op een succesvol stuk code reageert, dezelfde uitzondering kan genereren als het succesvolle stuk, en u kunt laat de tweede mogelijke uitzondering niet zomaar gaan, of keer direct terug bij succes (wat in mijn geval de draad zou doden), dan komt dit wel van pas.


Antwoord 14

Hier is nog een plek waar ik dit patroon graag gebruik:

while data in items:
     try
        data = json.loads(data)
     except ValueError as e:
        log error
     else:
        # work on the `data`

Antwoord 15

Ik zou nog een use-case toevoegen die duidelijk lijkt bij het afhandelen van DB-sessies:

   # getting a DB connection 
    conn = db.engine.connect()
    # and binding to a DB session
    session = db.get_session(bind=conn)
    try:
        # we build the query to DB
        q = session.query(MyTable).filter(MyTable.col1 == 'query_val')
        # i.e retrieve one row
        data_set = q.one_or_none()
        # return results
        return [{'col1': data_set.col1, 'col2': data_set.col2, ...}]
    except:
        # here we make sure to rollback the transaction, 
        # handy when we update stuff into DB
        session.rollback()
        raise
    else:
        # when no errors then we can commit DB changes
        session.commit()
    finally:
        # and finally we can close the session
        session.close()

16

Een elseBLOCK kan vaak bestaan ​​om functionaliteit die in elke exceptBLOCK.

try:
    test_consistency(valuable_data)
except Except1:
    inconsistency_type = 1
except Except2:
    inconsistency_type = 2
except:
    # Something else is wrong
    raise
else:
    inconsistency_type = 0
"""
Process each individual inconsistency down here instead of
inside the except blocks. Use 0 to mean no inconsistency.
"""

In dit geval wordt inconsistency_typeingesteld in elk behalve blok, zodat het gedrag wordt aangevuld in het geval van de no-fout in else.

Natuurlijk beschrijf ik dit als een patroon dat op een dag in uw eigen code kan verschijnen. In dit specifieke geval stelt u de inconsistency_typein op 0 vóór de tryBlok toch.


17

Een van de gebruikscenario’s die ik kan bedenken is onvoorspelbare uitzonderingen, die kunnen worden omzeild als u het opnieuw probeert. Bijvoorbeeld, wanneer de bewerkingen in het try-blok willekeurige getallen omvatten:

while True:
    try:
        r = random.random()
        some_operation_that_fails_for_specific_r(r)
    except Exception:
        continue
    else:
        break

Maar als de uitzondering kan worden voorspeld, moet u altijd vooraf validatie kiezen boven een uitzondering. Niet alles kan echter worden voorspeld, dus dit codepatroon heeft zijn plaats.


Antwoord 18

Ik vond elsehandig voor het afhandelen van een mogelijk onjuist configuratiebestand:

try:
    value, unit = cfg['lock'].split()
except ValueError:
    msg = 'lock monitoring config must consist of two words separated by white space'
    self.log('warn', msg)
else:
     # get on with lock monitoring if config is ok

Een uitzondering die de lock-configuratie leest, schakelt de vergrendelingsbewaking uit en ValueErrors logt een nuttig waarschuwingsbericht in.


Antwoord 19

Stel dat uw programmeerlogica afhangt van of een woordenboek een item met een bepaalde sleutel heeft. U kunt het resultaat van dict.get(key)testen met behulp van de if... else...constructie, of u kunt het volgende doen:

try:
    val = dic[key]
except KeyError:
    do_some_stuff()
else:
    do_some_stuff_with_val(val)

Antwoord 20

Het else:blok is verwarrend en (bijna) nutteloos. Het maakt ook deel uit van de instructies foren while.

Eigenlijk, zelfs op een if-statement, kan de else:op echt verschrikkelijke manieren worden misbruikt door bugs te creëren die erg moeilijk te vinden zijn.

Overweeg dit.

  if a < 10:
       # condition stated explicitly
   elif a > 10 and b < 10:
       # condition confusing but at least explicit
   else:
       # Exactly what is true here?
       # Can be hard to reason out what condition is true

Denk twee keer na over else:. Het is over het algemeen een probleem. Vermijd het behalve in een if-statement en overweeg zelfs om de else– voorwaarde te documenteren om het expliciet te maken.

Other episodes