It is important to be specific about what exception you're trying to catch when using a try/except block.
string = "abcd"
try:
string_int = int(string)
print(string_int)
except ValueError:
# Handle the exception
print('Please enter an integer')
Try/Excepts are powerful because if something can fail in a number of different ways, you can specify how you want the program to react in each fail case.
Answer from Nathan Jones on Stack OverflowIt is important to be specific about what exception you're trying to catch when using a try/except block.
string = "abcd"
try:
string_int = int(string)
print(string_int)
except ValueError:
# Handle the exception
print('Please enter an integer')
Try/Excepts are powerful because if something can fail in a number of different ways, you can specify how you want the program to react in each fail case.
Here it is:
s = "123"
try:
i = int(s)
except ValueError as verr:
pass # do job to handle: s does not contain anything convertible to int
except Exception as ex:
pass # do job to handle: Exception occurred while converting to int
If you want a one-liner like you've attempted, go with this:
variable = int(stringToInt) if stringToInt else None
This will assign variable to int(stringToInt) only if stringToInt is not empty AND is "numeric". If, for example stringToInt is 'mystring', a ValueError will be raised. If stringToInt is empty (''), it will assign variable to None.
To avoid ValueErrors, use a try-except:
try:
variable = int(stringToInt)
except ValueError:
variable = None
I think this is the clearest way:
variable = int(stringToInt) if stringToInt.isdigit() else None
Add a default option to int() to use if conversion fails - Ideas - Discussions on Python.org
python - How can I check if a string represents an int, without using try/except? - Stack Overflow
Converting strings to int without try/except?
Python: Convert a string to an integer - Stack Overflow
with positive integers you could use .isdigit:
>>> '16'.isdigit()
True
it doesn't work with negative integers though. suppose you could try the following:
>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True
it won't work with '16.0' format, which is similar to int casting in this sense.
edit:
def check_int(s):
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()
If you're really just annoyed at using try/excepts all over the place, please just write a helper function:
def represents_int(s):
try:
int(s)
except ValueError:
return False
else:
return True
>>> print(represents_int("+123"))
True
>>> print(represents_int("10.0"))
False
It's going to be WAY more code to exactly cover all the strings that Python considers integers. I say just be pythonic on this one.
Is there a way to convert strings to ints without a try/except clause, similar to the way you can get() dictionary items? I.e, something like
a=int('10', None)
b=int('10a', None)which gives 10 and None respectively? I know that try/except is a substitute for this, but something like this takes up way less space..
In this case you do have a way to avoid try/except, although I wouldn't recommend it (assuming your input string is named s, and you're in a function that must return something):
xs = s.strip()
if xs[0:1] in '+-': xs = xs[1:]
if xs.isdigit(): return int(s)
else: ...
the ... part in the else is where you return whatever it is you want if, say, s was 'iamnotanumber', '23skidoo', empty, all-spaces, or the like.
Unless a lot of your input strings are non-numbers, try/except is better:
try: return int(s)
except ValueError: ...
you see the gain in conciseness, and in avoiding the fiddly string manipulation and test!-)
I see many answers do int(s.strip()), but that's supererogatory: the stripping's not needed!
>>> int(' 23 ')
23
int knows enough to ignore leading and trailing whitespace all by itself!-)
import re
int(re.sub(r'[^\d-]+', '', your_string))
This will strip everything except for numbers and the "-" sign. If you can be sure that there won't be ever any excess characters except for whitespace, use gruszczy's method instead.
Actually there is a "built-in", single line solution that doesn't require introducing a helper function:
>>> s = "123"
>>> i = int(s) if s.isdecimal() else None
>>> print(i)
123
>>> s = "abc"
>>> i = int(s) if s.isdecimal() else None
>>> print(i)
None
>>> s = ""
>>> i = int(s) if s.isdecimal() else None
>>> print(i)
None
>>> s = "1a"
>>> i = int(s) if s.isdecimal() else None
>>> print(i)
None
In case you need to support negative numbers, too, the following extension considers one (or more) leading dashes/minus as the algebraic sign for negative numbers:
>>> s = "-123"
>>> i = int(s) if s.split("-", 1)[-1].isdecimal() else None
>>> print(i)
-123
See also:
- https://docs.python.org/3/library/stdtypes.html#str.isdecimal
- https://docs.python.org/3/library/stdtypes.html#str.split
This is a pretty regular scenario so I've written an "ignore_exception" decorator that works for all kinds of functions which throw exceptions instead of failing gracefully:
def ignore_exception(IgnoreException=Exception,DefaultVal=None):
""" Decorator for ignoring exception from a function
e.g. @ignore_exception(DivideByZero)
e.g.2. ignore_exception(DivideByZero)(Divide)(2/0)
"""
def dec(function):
def _dec(*args, **kwargs):
try:
return function(*args, **kwargs)
except IgnoreException:
return DefaultVal
return _dec
return dec
Usage in your case:
sint = ignore_exception(ValueError)(int)
print sint("Hello World") # prints none
print sint("1340") # prints 1340