Continue script execution after try/except exception with Python - python

Coming from other scripting languages I'm probably missing something fundamental here.
How do I continue on with the rest of the script when an exception is raised?
Example:
errMsg = None
try:
x = 1
y = x.non_existent_method()
except ValueError as e:
errMsg = str(e)
if errMsg:
print('Error')
else:
print('All good')
The script just fails. Is there a way to continue with the rest?
Thanks in advance

It should be Exception and not ValueError:
errMsg = None
try:
x = 1
y = x.non_existent_method()
except Exception as e:
errMsg = str(e)
if errMsg:
print('Error')
else:
print('All good')

Related

Python - while loop in try and catch

I work on hardware. The variables are physical and they can change at any moment
and I want to write a while-loop in try and catch,
but I want to do this shorter.
I wrote this:
try:
local_factory_param_multi_burn = _itwo_cnc_instance.get_parameters("factory_param_multi_burn")
except Exception as e:
raise Exception(f"Failed to get factory_param_multi_burn. {e}")
while local_factory_param_multi_burn != 3:
try:
local_factory_param_multi_burn = _itwo_cnc_instance.get_parameters("factory_param_multi_burn")
except Exception as e:
raise Exception(f"Failed to get factory_param_multi_burn. {e}")
I want that as long as the GET function does not return 3, the loop will continue, and the loop will break only when the GET function returns 3.
I want to do this:
try:
while _itwo_cnc_instance.get_parameters("factory_param_multi_burn") != 3
except Exception as e:
raise Exception(f"Failed to get factory_param_multi_burn. {e}")
Something like this?
var = _itwo_cnc_instance.get_parameters("factory_param_multi_burn")
while (var != 3):
try:
var = _itwo_cnc_instance.get_parameters("factory_param_multi_burn")
except Exception as e:
raise Exception(f"Failed to get factory_param_multi_burn. {e}")
break
If you don't raise exceptions, you can prevent breakint out of the while loop. Eg:
while local_factory_param_multi_burn != 3:
try:
local_factory_param_multi_burn = _itwo_cnc_instance.get_parameters("factory_param_multi_burn")
except Exception as e:
print(f"Failed to get factory_param_multi_burn. {e}")
This will now loop forever, until
local_factory_param_multi_burn == 3

Try/except for check string in Python

I would like to use Try/ecept to check if a string is really a string. I made the following code:
nome = input('Name: ')
try:
if not nome.isalpha() or nome == '':
raise ValueError('Invalid!')
else:
print(f'Name {nome} valid.')
except ValueError as e:
print(f'Error: {e}')
But, I would like to do it without using the raise command, just try/except.
Can anyone help me? I thank you.
The only way to trigger an exception without raising it yourself is to attempt something invalid, such as this:
nome = input('Name: ')
try:
f = float(nome)
except ValueError as e:
print('Is alpha')
else:
print('Not alpha')
Here I try to convert the input to a float, and if there are any alpha characters in the value, it will raise the ValueError exception.

Raise Except errors

Hi in my assessment i need to raise value errors but my code doesnt work and i dont know why can someone help me please
my code need to ask uurloon and gewerkte_uren if the user doesnt enter int/float he needs to get a error and the program must end when when the program is entered correctly.
can someone please help me :(
def program():
while True:
try:
uurloon = float(input("Hoeveel euro's verdien je per uur: "))
gewerkte_uren = float(input("Hoeveel uur heb je gewerkt: "))
salaris = (gewerkte_uren * uurloon)
print(f"{gewerkte_uren} uren werken levert €{salaris} op.")
except KeyboardInterrupt as a:
print(a)
raise
except OverflowError as b:
print(b)
raise
except ZeroDivisionError as c:
print(c)
raise
except IOError as d:
print(d)
raise
except IndexError as e:
print(e)
raise
except NameError as f:
print(f)
raise
except TypeError as g:
print(g)
raise
except ValueError as h:
print(h)
raise
program()
new code:
while True:
try:
uurloon = float(input("Hoeveel euro's verdien je per uur: "))
gewerkte_uren = float(input("Hoeveel uur heb je gewerkt: "))
salaris = (gewerkte_uren * uurloon)
print(f"{gewerkte_uren} uren werken levert €{salaris} op.")
break
except KeyboardInterrupt as a:
print(a)
except OverflowError as b:
print(b)
except ZeroDivisionError as c:
print(c)
except IOError as d:
print(d)
except IndexError as e:
print(e)
except NameError as f:
print(f)
except TypeError as g:
print(g)
except ValueError as h:
print(h)
i almost got it but when you enter the first input correctly and second wrong it goes back to the first input how can i program it that if you do the second one wrong it asks you to insert the second one again instead of running the program again?
You don't need the raise if you want your program to continue the run. That's how you threw exceptions.
You can catch the exception when Python can't convert the vars uurloon and gewerkte_uren to Float
Like that:
try:
uurloon = float(input("Hoeveel euro's verdien je per uur: "))
gewerkte_uren = float(input("Hoeveel uur heb je gewerkt: "))
salaris = (gewerkte_uren * uurloon)
print(f"{gewerkte_uren} uren werken levert €{salaris} op.")
except ValueError:
print("enter a number")

sys.exit() does not exit program when catching exceptions

This program checks molecular formulas. I want the program to exit as soon as it detects an error in a formula. For example, the formula "a", is incorrect.
When I run it through my code:
def readletter():
if q.peek() in string.ascii_lowercase:
print(q.peek())
return q.get()
else:
raise Formelfel("Förväntad liten bokstav.")
def readLetter():
if q.peek() in string.ascii_uppercase:
print(q.peek())
return q.get()
else:
raise Formelfel("Förväntad stor bokstav.")
def readAtom():
X = ""
try:
X += readLetter()
except Formelfel:
print("Missing capital letter at end of row "+getRest())
sys.exit()
return
try:
x = readletter()
atom = X+x
except (Formelfel, TypeError):
atom = X
if atom in ATOMER:
return
else:
raise Formelfel("Okänd atom.")
def readGroup():
if q.peek() in string.ascii_uppercase or q.peek() in string.ascii_lowercase:
try:
readAtom()
except:
print("Unknown atom at end of row "+getRest())
sys.exit()
I get this output:
Missing capital letter and end of row a
Unknown atom at end of row
Why is this? I called sys.exit() before print("Unknown atom at end of row "+getRest()) so why does it still execute? I want only the first row of the output to be printed.
sys.exit raises a SystemExit exception. You are catching it with your except clause.
What you should do instead is catch a more specific class of exceptions, which does not include SystemExit.
Catching Exception will work:
def readGroup():
if q.peek() in string.ascii_uppercase or q.peek() in string.ascii_lowercase:
try:
readAtom()
except Exception:
print("Unknown atom at end of row "+getRest())
sys.exit()
You can learn more about exceptions and SystemExit in the docs.
Note that you should ideally catch something more specific than Exception (which is very broad, and may catch exceptions you don't intend to catch).
Because in python exit event is processed as SystemExit exception

Python run something only if exception is met

I want to run a line of code if any of the exceptions are met, but not if the try succeeds, a bit like the opposite of else when using try/except.
Currently I have exceptionOccured to set to True if an exception occurs, but I'm guessing there should be a more pythonic way of doing this.
Here's the current code I have, it was an attempt to edit values in a dictionary from a list, and create the keys if they don't exist. How would I redo the exceptions so that exceptionOccured is not needed?
dictionaryValue = {"data": dict.fromkeys( [0, 1, 2, 3] ), "data2": {0: "test",1:"test2"}}
reducedDictionary = dictionaryValue
valueList = ["data", 1, 64, "Testing", "value"]
canOverwriteKeys = True
for i in valueList[:-2]:
exceptionOccured = False
try:
if type( reducedDictionary ) != dict:
raise ValueError()
elif reducedDictionary.get( i, False ) == False:
raise KeyError()
except ValueError:
print "not dictionary"
reducedDictionary = {}
exceptionOccured = True
except KeyError:
print "key doesn't exist"
exceptionOccured = True
if exceptionOccured or ( type( reducedDictionary[i] ) != dict and canOverwriteKeys ):
print "setting key value"
reducedDictionary[i] = {}
reducedDictionary = reducedDictionary[i]
reducedDictionary[valueList[-2]] = valueList[-1]
print dictionaryValue
Edit: Improved the code based on the answers, thanks :)
def editDictionary( dictionaryName, listOfValues, canOverwriteKeys=True ):
reducedDictionary = dictionaryName
for i in valueList[:-2]:
if type( reducedDictionary ) != dict:
reducedDictionary = {}
try:
if reducedDictionary.get( i, False ) == False:
raise ValueError()
elif type( reducedDictionary[i] ) != dict:
if not canOverwriteKeys:
return
raise KeyError()
except( ValueError, KeyError ):
reducedDictionary[i] = {}
except:
print "Something went wrong"
return
reducedDictionary = reducedDictionary[i]
reducedDictionary[valueList[-2]] = valueList[-1]
Just catch both exceptions in one handler:
try:
# ...
except (ValueError, KeyError) as e:
if isinstance(e, ValueError):
print "not dictionary"
reducedDictionary = {}
else:
print "key doesn't exist"
print "setting key value"
reducedDictionary[i] = {}
If your exception handlers are more complex, you could also use a function:
def handle_common_things():
# things common to all exception handlers
try:
# ...
except Exception1:
# do exception-specific things
handle_common_things()
except Exception2:
# do exception-specific things
handle_common_things()
I'd probably go with Martijn's answer, but you can also wrap your try/except block in another layer of try/except (and in real code I'd frown on using a bare except like this, or more likely define a new exception that's thrown from inside any except: clauses that you want to detect)
def exception_test(val):
try:
try:
result = 1.0 / val
except ZeroDivisionError:
print "Divide by zero"
raise
else:
print "1 / {0} = {1}".format(val, result)
except:
print "there was an exception thrown."
>>> exception_test(2.0)
1 / 2.0 = 0.5
>>> exception_test(0)
Divide by zero
there was an exception thrown.

Categories