我在 Python 3 中接收数字作为字符串,并希望将它们作为字符串传输以保持准确性,以便上游服务器可以将数字字符串转换为
decimal.Decimal
而不会损失准确性。
[管理员:我反复搜索 Stack Overflow 和其他资源,找不到任何人询问或回答这个特定问题。]
str.format
提供给定的浮点格式(如下)?表明这是不可能的,这是一个可以接受的答案。
简而言之,该格式只是提供始终至少有一位小数,即使只是尾随零,但绝不执行任何舍入。
我想可能有一个 Formatter class 解决方案,如果可用的话,这是可以接受的,但
str.format
解决方案是首选。
我有兴趣知道 f-strings 是否也能实现这一点。在这种情况下,使用 f-strings 并不是首选的答案,但了解 f-strings 是否可以提供这种格式(而不只是将演示的表达式打包在 f-string 中以供执行)会很有趣:这只是移动所需的代码进入二级评估环境)。
为了区分数字和
int
仅当数字不带任何小数位时,格式才必须将 ".0"
后缀为整数,但要准确保留所显示的所有小数位,即使其中包含尾随零。
有一种正在考虑的替代解决方案,即去除所有尾随小数位为零,但为整数保留一个且仅一个尾随小数零(当然保留所有非零小数位而不进行四舍五入)。
传入的字符串预计是有效的
int
或 Decimal
。接收只有小数点且没有小数位的整数的特殊情况是无效的,不会发生(无需处理"42."
)。不会出现空字符串(""
)。
仅配置大量小数位是不可接受的(
"{:.28f}".format(1)
)。
据我所知,这应该是必需的行为。使用
format
寻找此行为:
for number in ("42", "4200", "42.0000", "42.34", "42.3400", "42.3456"):
string = "." in number and number or number + ".0"
print(number, "=>", string)
42 => 42.0
4200 => 4200.00
42.0000 => 42.0000
42.34 => 42.34
42.3400 => 42.3400
42.3456 => 42.3456
正在进行中:目前这是不正确的,很快就会改变
这种替代行为也是可以接受的。
for number in ("42", "42.0000", "42.34", "42.3400", "42.3456"):
stripped = number.rstrip("0").rstrip(".")
string = "." in stripped and stripped or stripped + ".0"
print(number, "=>", string)
42 => 42.0
42.0000 => 42.0
42.34 => 42.34
42.3400 => 42.34
42.3456 => 42.3456
f-string
可能有帮助:
# For whole numbers add .0 if they are presented without any decimal places
fmt_string = "{{:.{}f}}".format(1 if number % format_string = "{{:.{}f}}".format(1 if number % 1 == 0 else 0)
# For Decimal, preserve all decimal places
fmt_string = "{:." + str(number_str[::-1].find('.') + 1) + "f}"