【问题标题】:locale.setlocale(LC_NUMERIC): how to make it work on Windowslocale.setlocale(LC_NUMERIC):如何让它在 Windows 上工作
【发布时间】:2015-11-27 07:48:22
【问题描述】:

我在Win10下。这是我的小脚本:

import locale
locale.setlocale(locale.LC_NUMERIC,"rus")

print locale.localeconv()

fv = 2.5
print str(fv)

打印出来:

{'mon_decimal_point': '', 'int_frac_digits': 127, 'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '\xa0', 'n_sign_posn': 127, 'decimal_point': ',', 'int_curr_symbol': '', 'n_cs_precedes': 127, 'p_sign_posn': 127, 'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '', 'n_sep_by_space': 127, 'mon_grouping': [], 'p_cs_precedes': 127, 'positive_sign': '', 'grouping': [3, 0]}
2.5

我们看到小数点是',';为什么然后 2,5 打印为 2.5 ??

谢谢

【问题讨论】:

    标签: python windows localization internationalization


    【解决方案1】:

    您需要调用locale.str 方法,而不是普通的str 构造函数。

    import locale
    locale.setlocale(locale.LC_NUMERIC,"ru_RU.utf8")
    
    print locale.localeconv()
    
    fv = 2.5
    print locale.str(fv)
    

    输出

    {'mon_decimal_point': '', 'int_frac_digits': 127, 'p_sep_by_space': 127, 'frac_digits': 127, 'thousands_sep': '\xc2\xa0', 'n_sign_posn': 127, 'decimal_point': ',', 'int_curr_symbol': '', 'n_cs_precedes': 127, 'p_sign_posn': 127, 'mon_thousands_sep': '', 'negative_sign': '', 'currency_symbol': '', 'n_sep_by_space': 127, 'mon_grouping': [], 'p_cs_precedes': 127, 'positive_sign': '', 'grouping': [3, 3, 0]}
    2,5
    

    下面是一些代码,演示了一个简单的区域感知打印功能。正如我在评论中提到的,通常最好在打印时提供明确的格式规范。当然,当你不需要花哨的输出时,基本的print a, b, c 表单很方便,例如在非常简单的脚本和开发/调试期间,但是当你将它用于除了最简单的情况之外的任何情况时,这样的输出往往看起来很草率。

    简单的format_string % tuple_of_values 样式格式不支持区域设置。 locale 模块确实提供了几个使用旧的% 格式化协议的函数(formatformat_string)。然而,% 样式格式在现代 Python 中被逐步淘汰,取而代之的是内置 format 函数和 str.format 支持的新格式格式。那些format 函数为数字提供本地感知格式类型说明符:n;下面的代码说明了它的用法。

    # -*- coding: utf-8 -*-
    
    import locale
    locale.setlocale(locale.LC_NUMERIC, "ru_RU.utf8")
    
    def lprint(*args):
        lstr = locale.str
        print ' '.join([lstr(u) if isinstance(u, float) else str(u) for u in args])
    
    lprint(1.25, 987654, 42.0, 2.33, u"Росси́я".encode('UTF-8'), 3.456)
    print locale.format_string('%.2f %d %.3f %.3f %s %f', (1.25, 987654, 42.0, 2.33, u"Росси́я", 3.456))
    print '{0:n} {1:n} {2:n} {3:n} {4:n} {5}'.format(1.25, 987654, 42.0, 2.33, 3.456, u"Росси́я".encode('UTF-8'))
    

    输出(在设置为使用 UTF-8 编码的终端中)

    1,25 987654 42 2,33 Россия 3,456
    1,25 987654 42,000 2,330 Россия 3,456000
    1,25 987 654 42 2,33 3,456 Россия
    

    请注意,在第二行中,我们可以传递一个 Unicode 字符串对象,因为locale.format_string 知道编码。在输出的最后一行 987654 打印有千位分隔符,在俄语语言环境中是一个空格。

    如果您使用 Python 2.7(或更高版本),则可以将 '{0:n} {1:n} {2:n} {3:n} {4:n} {5}' 格式字符串简化为 '{:n} {:n} {:n} {:n} {:n} {}'。当然,在 Python 3 中,print 语句不再可用:它已被 print 函数取代;在 Python 2 的更高版本中,您可以通过在任何其他 import 语句之前执行 from __future__ import print_function 来访问该函数。

    【讨论】:

    • 太棒了!那是在文档中写的!!我的可怜.. 仅针对这种情况:如果我希望脚本中的所有“打印”-s 使用给定的语言环境/编码打印值,有没有办法做到这一点?像“使用CP1251”之类的?
    • @62mkv:不是这样,这与 Python 口号的精神背道而驰:“显式优于隐式”。您可以编写一个简单的函数来代替print 语句。但是,通常最好在打印时提供明确的格式,而不是依赖默认格式。我将在我的答案中添加几个示例。
    猜你喜欢
    • 2016-09-19
    • 2012-02-14
    • 2014-08-24
    • 2017-11-07
    • 2012-03-10
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多