Requirements:
- Input can be either string or number
- If input could be treated as an int without loss of precision, cast to int
- If input could be treated as a float, cast to float
Here is the section of code where I am using this.
def make_operand(symbol, left=None, right=None):
valid_symbols = ['*', '/', '+', '-']
if symbol in valid_symbols:
return Operand(symbol, left, right)
as_int = re.compile("^-?[0-9]+$").match(str(symbol))
as_float = re.compile("^[-+]?[0-9]*\.?[0-9]+$").match(str(symbol))
as_number = int(symbol) if as_int else float(symbol) if as_float else None
if as_number:
return NumericOperand(as_number)
raise ValueError("Invalid symbol or number")
This works but it looks messy and smells wrong.
An implementation using try blocks also works, but seems less simple:
as_number = None
try:
as_float = float(symbol)
except ValueError:
as_float = None
if as_float:
as_int = int(as_float)
as_number = as_int if as_int == as_float else as_float
if as_number:
return NumericOperand(as_number)
raise ValueError("Invalid symbol or number")
Is there a better approach, or is one of these close to the Pythonic method of doing things?