2017-08-31 67 views
4

我想将字符串转换为python decimal。如何将字符串转换为德语区域设置的Python Decimal(用逗号代替点)

这工作

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)) 

返回float和错误

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

是否有将字符串转换不通过浮动或hackier解决方案手动转换它正确的方式? FYA,我目前哈克的解决办法是:

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

有什么错'小数(atof(mystr))'? (注意你的测试结果不匹配:在这里我得到'1234.56') –

+0

@ Jean-FrançoisFabre我已经使用过了,并且在添加我生成的小数时会产生令人讨厌的舍入错误。对我来说,它也感觉像是一个黑客... – 576i

+1

是的,有一些舍入误差,但它是由于浮点表示,它不是真正的四舍五入。只是'Decimal'不能处理区域设置。对我来说,这看起来不像一个黑客。 –

回答

4

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

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的建议。

+0

这看起来很有前途(并且非常好)。我会检查它,并将其解决,如果它适用于我。 – 576i

+0

工程(几乎)和足够接受作为答案。我必须在使用Python 3.6的德语Windows机器上使用'locale.setlocale(locale.LC_NUMERIC,'German_Germany.1252')',您的设置会导致“locale.Error:不支持的语言环境设置”。 – 576i

+0

@ 576i,我在ubuntu上测试过。语言环境名称可能是特定于操作系统的,应该安装使用。 – newtover

0

这里有一个想法,基本上我们在转换之前格式化根据语言环境的字符串:

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))) 
0

区域设置选项并没有为我工作,也许是因为我很少该机在国际化的道路上,所以我提出只依赖于字符串操作的解决方案:

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('.', ',')) 
相关问题