【问题标题】:locale.getlocale() problems on OSXOSX 上的 locale.getlocale() 问题
【发布时间】:2009-10-27 09:42:31
【问题描述】:

我需要获取系统语言环境来做很多事情,最终我想使用 gettext 翻译我的应用程序。我打算在 Linux 和 OSX 上分发它,但我在 OSX Snow Leopard 上遇到了问题:

$ python
Python 2.5.2 (r252:60911, Jan  4 2009, 17:40:26) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
'sv_SE.UTF-8'
>>> locale.getlocale()
('sv_SE', 'UTF8')

$ python
Python 2.6.1 (r261:67515, Jul  7 2009, 23:51:51) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.setlocale(locale.LC_ALL, '')
'C'
>>> locale.getlocale()
(None, None)

两个系统都使用瑞典语。在 Linux 上,环境变量 LANG 已设置为“sv_SE.UTF-8”。如果我将该变量传递给 OSX 上的 python(改为LANG="sv_SE.UTF-8" python),则可以很好地检测到语言环境。但是locale.getlocale()不应该能够获取操作系统具有的任何语言吗?我不想强迫用户设置LANGLC_ALL 或任何环境变量。

locale 命令的输出:

$ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=

【问题讨论】:

  • locale(在 shell 中)在同一终端窗口中的输出是什么?
  • 将语言环境输出添加到原始帖子。

标签: python macos localization osx-snow-leopard locale


【解决方案1】:

在 OSX(Smow Leopard 10.6.1)上奇怪

$ python
Python 2.6.1 (r261:67515, Jul  7 2009, 23:51:51) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.  
>>> import locale
>>> locale.getlocale()
(None, None)
>>> locale.setlocale(locale.LC_ALL, '')
'en_GB.UTF-8'
>>> locale.getlocale()
('en_GB', 'UTF8')

编辑:

我刚刚在apple python mailing list上找到了这个

基本上它取决于运行时在您的环境中设置的内容(LANG、LANGUAGE、LC_ALL 之一)我的 shell 环境中有 LANG=en_GB.UTF-8

【讨论】:

  • 奇怪。在最初的帖子中,我使用的是 iTerm,但如果我使用 Terminal.app,我会收到一个错误(ValueError:未知语言环境:UTF-8)。语言环境看起来很奇怪:'C/UTF-8/C/C/C/C'。也许我的系统不知何故搞砸了,但它是全新安装的 Snow Leopard。
  • 查看我的编辑以了解更改出现的原因 - 你的系统没有搞砸(当然不是所有的 OSX python) - 抱歉应该在我编辑时添加了这个
  • 我现在看到了您的链接,据我所知,“它无法完成”,因为 OSX 不使用 LANG 或 LC_ALL。我对 __CF_USER_TEXT_ENCODING 变量很感兴趣,但解析它似乎有点愚蠢。 IMO getlocale() 应该调用适当的 API:s 并为您解析,而不是依赖于某些环境变量。
  • @pojo,你说得很对:这是一个 python 错误,看起来他们最终可能会使用本地语言环境 API 而不是环境变量。唉,还是没修好。 bugs.python.org/issue18378
【解决方案2】:

看来您可以通过更改环境变量 LC_ALL 来更改语言环境。

$ export LC_ALL=C
$ python
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale()
(None, None)
>>> locale.setlocale(locale.LC_ALL, "")
'C'
>>> locale.getlocale()
(None, None)    

$ export LC_ALL=en_GB.UTF-8
$ python
Python 2.5.1 (r251:54863, Feb  6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.getlocale()
(None, None)
>>> locale.setlocale(locale.LC_ALL, "")
'en_GB.UTF-8'
>>> locale.getlocale()
('en_GB', 'UTF8')

【讨论】:

  • 但我不明白必须以这种方式明确设置 LC_ALL 才能让我的应用程序正确检测语言。
【解决方案3】:

确实是一个可怕的黑客,但我插入了这个:

import platform

# ...

# XXX horrendous OS X invalid locale hack
if platform.system() == 'Darwin':
    import locale
    if locale.getlocale()[0] is None:
        locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

mine 程序的早期阶段。之后,我可以在与我相关的所有操作系统上使用未经修改的 shell 环境运行我的程序(我的程序会找出稍后在处理过程中使用的语言)。

【讨论】:

  • +1。它一个可怕的hack,但鉴于这是一个Python错误,这是必要的。 (我的回答中有更多详细信息;P)
【解决方案4】:

来自here:尝试添加或编辑~/.profile~/.bash_profile 文件,以便在启动新会话时正确导出您的区域设置。

export LC_ALL=en_US.UTF-8  
export LANG=en_US.UTF-8

【讨论】:

  • 1) 语言环境变量可能由终端仿真程序设置,所以这只是隐藏问题。 2) 语言环境变量已经被正确设置,但 python 不理解它们。
【解决方案5】:

老问题,但这可能对其他人有所帮助:这是一个 Python 错误,截至 2016 年 3 月,在 Python 2 或 3 中仍未解决:https://bugs.python.org/issue18378

总结是,Python 假定类似于 GNU 的语言环境,并且拒绝(POSIXly 正确的)分歧,例如 BSD 环境中的分歧(OS X 也是如此)。而且 UTF8 语言环境存在于 BSD 中,而不是 Linux 中,因此存在问题。

至于解决方案或调试:本地环境变量可以由 Terminal.app 设置(参见首选项 - 配置文件 - 高级 - 国际;对于 iTerm 或其他类似)。因此可以在终端窗口中找到设置的语言环境变量,但在运行打包的应用程序时找到未设置的变量。

对于某些情况(如 Python 2.7 和 3.5 中的 Sphinx 由于“ValueError: unknown locale: UTF-8”而在 OS X 中死亡),禁用首选项复选框以设置语言环境变量是解决方案。

但这可能会导致其他程序出现问题:如果未设置语言环境变量,bash 4.3(来自 MacPorts)将在每次提示时抱怨“警告:setlocale:LC_CTYPE:无法更改语言环境():没有这样的文件或目录" ...

因此,鉴于该错误在 Python 中,解决方法可能应该在 python 程序中完成(如@Jacob Oscarson 的回答)或 python 调用(通过将语言环境变量设置为一些适当的值)。

【讨论】:

    【解决方案6】:

    我的设置

    $ system_profiler SPSoftwareDataType
    Software:
    
        System Software Overview:
    
          System Version: macOS 11.4 (20F71)
          Kernel Version: Darwin 20.5.0
    

    System Preferences > Language & Reginon中的当前语言为English时,则

    Python 3.9.5 (v3.9.5:0a7dcbdb13, May  3 2021, 13:17:02) 
    [Clang 6.0 (clang-600.0.57)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import locale
    >>> locale.getdefaultlocale()
    (None, 'UTF-8')
    >>> 
    

    以及底层shell命令输出

    $ locale
    LANG=""
    LC_COLLATE="C"
    LC_CTYPE="UTF-8"
    LC_MESSAGES="C"
    LC_MONETARY="C"
    LC_NUMERIC="C"
    LC_TIME="C"
    LC_ALL=
    

    当当前语言为Chinese, Simplified时,则

    $ py3
    Python 3.9.5 (v3.9.5:0a7dcbdb13, May  3 2021, 13:17:02) 
    [Clang 6.0 (clang-600.0.57)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import locale
    >>> locale.getdefaultlocale()
    ('zh_CN', 'UTF-8')
    >>> 
    

    以及底层shell命令输出

    $ locale
    LANG="zh_CN.UTF-8"
    LC_COLLATE="zh_CN.UTF-8"
    LC_CTYPE="zh_CN.UTF-8"
    LC_MESSAGES="zh_CN.UTF-8"
    LC_MONETARY="zh_CN.UTF-8"
    LC_NUMERIC="zh_CN.UTF-8"
    LC_TIME="zh_CN.UTF-8"
    LC_ALL=
    

    请注意,每当我们在系统偏好设置中切换系统语言时,我们必须重新启动终端才能看到差异。

    【讨论】:

      猜你喜欢
      • 2014-01-04
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多