我还没有尝试装饰器或功能内的功能,但这种当前的非pythonic方法似乎有点复杂。当我检查return_type(3次)时,我不喜欢我需要重复自己吗?
欢迎任何建议,特别是如果可以优雅地处理重复。请注意,如果对象是一个数字,我对众多参考测试并不感兴趣,因为我相信这部分已经包含在我的解决方案中。我有兴趣解决3x重复问题以处理返回类型。此外,虽然我很欣赏locale方法是处理国际化的更严格的方法,但我更喜欢简单地允许调用者更灵活地选择字符。
由于
def is_number(obj, thousand_sep=',', decimal_sep=None, return_type='b'):
""" determines if obj is numeric.
if return_type = b, returns a boolean True/False
otherwise, it returns the numeric value
Examples
--------
>>> is_number(3)
True
>>> is_number('-4.1728')
True
>>> is_number('-4.1728', return_type='n')
-4.1728
>>> is_number(-5.43)
True
>>> is_number("20,000.43")
True
>>> is_number("20.000,43", decimal_sep=",", thousand_sep=",")
True
>>> is_number("20.000,43", decimal_sep=",", thousand_sep=".", return_type="n")
20000.43
>>> is_number('Four')
False
# I am a few light years away from working that one out!!!
"""
try:
if is_string(obj):
if decimal_sep is None:
value = float(obj.replace(thousand_sep, ""))
else:
value = float(obj.replace(thousand_sep, "").replace(decimal_sep, "."))
if return_type.lower() == 'b':
return True
else:
return value
else:
value = float(obj)
if return_type.lower() == 'b':
return True
else:
return value
except ValueError:
return False
if return_type.lower() == 'b':
return False
else:
return None
答案 0 :(得分:2)
我可能将这些逻辑分开......我认为这可以做你想做的事情......
def get_non_base_10(s):
#support for base 2,8,and 16
if s.startswith("O") and s[1:].isdigit():
return int(s[1:],8)
elif s.startswith("0x") and s[2:].isdigit():
return int(s[2:],16)
elif s.startswith("0b") and s[2:].isdigit():
return int(s[2:],2)
def get_number(s,decimal_separator=".",thousands_separator=","):
if isinstance(s,basestring):
temp_val = get_non_base_10(s)
if temp_val is not None:
return temp_val
s = s.replace(decimal_separator,".").replace(thousands_separator,"")
try:
return float(s)
except ValueError:
return "nan"
def is_number(s,decimal_separator=".",thousands_separator=",",return_type="b"):
numeric = get_number(s,decimal_separator,thousands_separator)
return numeric if return_type != "b" else numeric != "nan"
答案 1 :(得分:2)
使用正则表达式,您可以这样做:
import re
regex = re.compile( r'[+-]{0,1}\d{1,3}(,\d\d\d)*(\.\d+)*'
现在,如果您有字符串txt
,请执行以下操作
regex.sub( '', txt, count=1 )
如果该字符串是,
为千位分隔符且.
为小数分隔符的数字,则最终会出现一个空字符串。
此方法强制执行严格 3位千位分隔符。所以例如20,0001.43
不是数字,因为千位分隔符是错误的。 1220,001.43
不是一个数字,因为它缺少,
。
def numval( txt ):
import re
regex = re.compile( r'[+-]{0,1}\d{1,3}(,\d\d\d)*(\.\d+)*'
if regex.sub( '', txt.strip(' '), count=1 ) != '':
raise ValueError ( 'not a number' )
else:
return float( txt.replace( ',', '' ))