要求:
>输入可以是字符串或数字
>如果输入可以被视为int而不会丢失精度,则转换为int
>如果输入可以被视为浮点数,则转换为浮点数
这是我使用它的代码部分.
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")
这有效,但它看起来很乱,闻起来有点不对劲.
使用try块的实现也可以,但似乎不太简单:
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")
有更好的方法,还是其中一种接近Pythonic的做法?
最佳答案 如果您不介意第三方模块,那么有一个名为
fastnumbers的C-exension模块就是为此目的而设计的.
fast_real功能完全符合您的要求(假设您使用coerce = True,可在fastnumbers上使用> = 0.7.4).
完全披露,我是作者.
>>> from fastnumbers import fast_real
>>> fast_real('56')
56
>>> fast_real('56.0')
56
>>> fast_real('56.07')
56.07
>>> fast_real('56.07 lb')
'56.07 lb'
>>> fast_real(56.07)
56.07
>>> fast_real(56.0)
56.0
>>> fast_real(56.0, coerce=True)
56
>>> fast_real(56)
56
>>> fast_real('56.07 lb', raise_on_invalid=True)
Traceback (most recent call last):
...
ValueError: could not convert string to float: '56.07 lb'