What's the best way to get a number as input from python while maintaining type
I'm trying to get a number as CLI input from python. Valid input should be either an int or a float and I need t开发者_高级运维o maintain type. So validating an int and returning a float wouldn't work.
This is the best thing I've been able to come up with and it's not all that good.
def is_valid(n):
try:
if '.' in n: return float(n)
return int(n)
except ValueError:
print "try again"
def num_input(s):
n = raw_input(s)
while is_valid(n) is None:
n = raw_input(s)
return is_valid(n)
valid_num = num_input("Enter a valid number: ")
Clearly this isn't the best way.
use a for loop to try all the conversions, I added complex type for demonstration:
def is_valid(n):
for t in (int, float, complex):
try:
return t(n)
except ValueError:
pass
raise ValueError("invalid number %s" % n)
print is_valid("10")
print is_valid("10.0")
print is_valid("1+3.0j")
def num_input(prompt, error):
while True:
result = raw_input(prompt)
for candidate in (int, float):
try: return candidate(result)
except ValueError: pass
print error
Try using the decimal module which will allow you to maintain exactly the precision of the entered number eg:
import decimal
def num_input(s):
while True:
try:
return decimal.Decimal(raw_input(s))
except decimal.InvalidOperation, e:
print e.message
valid_num = num_input("Enter a decimal number: ")
print 'ANSWER: ', valid_num
See: http://docs.python.org/library/decimal.html
After considering the early answers and thinking about it a bit more the solution I came up with is:
def num_input(prompt, error):
s = raw_input(prompt)
for t in (int, float, complex):
try: return t(s)
except ValueError: pass
print error
return num_input(prompt, error) #better get it in the first 1k tries
I really want an input function not just a validation function; however, I think HYRY's suggestion to loop over int, float, complex is a good one. I took win's suggestion to use recursion instead of looping, understanding that a really confused and persistent user could exceed the max recursion depth. Although I don't need it now, I think Karl Knechtel is correct in making the error an arg instead of hard coded.
精彩评论