【问题标题】:How do I convert a string to a Python Decimal in German locale (with comma instead of a point)如何在德语语言环境中将字符串转换为 Python 十进制(用逗号而不是点)
【发布时间】:2018-02-09 07:49:21
【问题描述】:

我正在尝试将字符串转换为 python 小数。

这行得通

from decimal import *
mystr = '123.45'
print(Decimal(mystr))

但是当我想使用千位分隔符和语言环境时,它没有。 转换为浮点数可以正常工作。

from locale import *
setlocale(LC_NUMERIC,'German_Germany.1252')
from decimal import *
mystr = '1.234,56'
print(atof(mystr))
print(Decimal(mystr))

返回浮点数和错误

1234.56
InvalidOperation: [<class 'decimal.ConversionSyntax'>] 

是否有正确的方法来转换字符串,而无需通过浮动或更黑客的解决方案手动转换它? FYA,我目前的 hacky 解决方案是:

 print(Decimal(f'{atof(mystr):2.2f}'))

【问题讨论】:

  • Decimal(atof(mystr)) 有什么问题? (注意你的测试输出不匹配:这里我得到1234.56
  • @Jean-FrançoisFabre 我已经使用过它,并且在添加我以这种方式生成的小数时会出现令人讨厌的舍入错误。这对我来说也像是一个黑客......
  • 是的,有一些舍入错误,但这是因为浮点表示,它不是真正的舍入。只是Decimal 不处理语言环境。对我来说,这似乎不是一个黑客。
  • 也许是一个 python PEP(没那么容易)。这将是一个有趣的功能。 @MartijnPieters 对此有任何想法,这是个好主意吗? (抱歉打扰了)
  • 我没有午休,好吧,我和我的朋友苹果一起吃了:) 这么好的主意可以被接受。困难似乎是:如何正确编写 PEP。当然,如果您有一些实施想法,那会有所帮助。

标签: python python-3.x decimal type-conversion


【解决方案1】:

语言环境选项对我不起作用,可能是因为我在这台机器上的国际化方式很少,所以我提供了一个仅依赖于字符串操作的解决方案:

numbr = 1234.56

mystr = '{:,.2f}'.format(numbr) # Ugly American format
mystr_orig = mystr # Ugly (but saved for later!) American format

mystr = mystr.replace(',', '{0}')
mystr = mystr.replace('.', '{1}')

print(mystr_orig)
print(mystr.format('.', ','))

【讨论】:

    【解决方案2】:

    我做了一些研究,这里是解决方案:

    import decimal
    import locale
    
    locale.setlocale(locale.LC_ALL, 'de_DE')
    mystr = '1.234,56'
    num = locale.atof(mystr, decimal.Decimal)
    
    print('{}'.format(num))
    print('{:n}'.format(num))
    

    1234.56
    1.234,56
    

    在后台locale.atof 调用delocalize 函数,这完全符合@lsma 的建议。

    【讨论】:

    • 这看起来很有希望(并且非 hacky)。如果它对我有用,我会检查它并标记它已解决。
    • 工作(几乎)并且足以接受作为答案。我必须在使用 Python 3.6 的德国 Windows 机器上使用 locale.setlocale(locale.LC_NUMERIC,'German_Germany.1252'),您的设置导致“locale.Error: unsupported locale setting”。
    • @576i,我在 ubuntu 上测试过。语言环境名称可能是特定于操作系统的,应该安装后才能使用。
    【解决方案3】:

    这里有个思路,基本上我们在转换之前根据locale格式化字符串:

    from locale import *
    from decimal import *
    
    def format_decimal(s):
       return '{0:n}'.format(s)
    
    setlocale(LC_NUMERIC,'German_Germany.1252')
    thousandSep = localeconv()['thousands_sep']
    decimalPoint = localeconv()['decimal_point']
    mystr = '1.234,56'.replace(thousandSep, '').replace(decimalPoint, '.')
    print(atof(mystr))
    print(format_decimal(Decimal(mystr)))
    

    【讨论】:

      猜你喜欢
      • 2015-11-22
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 2021-11-05
      • 2013-01-03
      相关资源
      最近更新 更多