Python: specifieke uitzondering vangen

Ik wil een specifieke ValueErroropvangen, niet zomaar een ValueError.
Ik heb zoiets als dit geprobeerd:

try: maquina['WPF'] = macdat(ibus, id, 'WPF')
except: ValueError, 'For STRING = ’WPF’, this machine is not a wind machine.':
    pass

Maar het roept een SyntaxError: can't assign to literal.
Toen probeerde ik:

try: maquina['WPF'] = macdat(ibus, id, 'WPF')
except ValueError, e:
    if e != 'For STRING = ’WPF’, this machine is not a wind machine.':
        raise ValueError, e

Maar het roept de uitzondering op, zelfs als het degene is die ik wil vermijden.


Antwoord 1, autoriteit 100%

in except ValueError,eis eeen instantie van de uitzondering, geen tekenreeks. Dus als je test of eniet gelijk is aan een bepaalde string, is die test altijd False. Probeer:

if str(e) != "..."

in plaats daarvan.

Voorbeeld:

def catch(msg):
    try:
        raise ValueError(msg)
    except ValueError as e:  # as e syntax added in ~python2.5
        if str(e) != "foo":
            raise
        else:
            print("caught!")
catch("foo")
catch("bar")

Normaal gesproken wil je niet echt vertrouwen op de foutmelding als je er iets aan kunt doen — het is een beetje te kwetsbaar. Als je controle hebt over de aanroepbare macdat, kun je in plaats van een ValueErrorin macdatte verhogen, een aangepaste uitzondering maken die erft van ValueError:

class MyValueError(ValueError): pass

Dan kun je alleen MyValueErroropvangen en andere ValueErrors laten doorgaan om door iets anders te worden betrapt (of niet). Eenvoudige except ValueErrorzal dit type uitzondering nog steeds opvangen, dus het zou zich hetzelfde moeten gedragen in andere code die ook ValueErrors van deze functie zou kunnen opvangen.


Antwoord 2, autoriteit 6%

De methode voor de laatste is correct (maar print repr(e) om te zien waarom het niet werkt).

Als u echter wilt dat de informatie over de uitzondering correct is, moet u geen nieuwe uitzondering maken (zoals u nu doet), maar dezelfde. Anders zal meer code die het opvangt, of de foutmelding als het niet wordt gevangen, uw code als de bron weergeven, terwijl het de originele bron zou moeten zijn.

Gebruik hiervoor raise zonder argument (uiteraard binnen het blok behalve, anders is er geen “huidige” uitzondering).


Antwoord 3, autoriteit 2%

U kunt hiervoor gebruiken: type(e)en e.args. Het geeft een tuple terug, match de tuple met die van jou.

Other episodes