locale.getpreferredencoding() - 为什么重置string.letters?

时间:2014-05-19 16:53:04

标签: python

>>> import string
>>> import locale
>>> string.letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> locale.getpreferredencoding()
'UTF-8'
>>> string.letters
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

对此有任何解决方法吗?

平台:Linux Python2.6.7和Python2.7.3似乎受到影响,在Python3中工作正常(使用ascii_letters

1 个答案:

答案 0 :(得分:15)

注意:OP解决此问题的方法是将encoding='UTF-8'传递给open来电。如果你遇到这个问题并且只是寻找修复,这是有效的。帖子的其余部分强调为什么


会发生什么

正如卢卡斯所说,文件指明:

  

在某些系统上,必须调用setlocale()来获取用户首选项

最初,string.letters设置为返回lowercase + uppercase

lowercase = 'abcdefghijklmnopqrstuvwxyz'
uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
letters = lowercase + uppercase

但是,当您致电getpreferredencoding()时,_locale模块会在PyDict_SetItemString(string, "letters", ulo);内生成fixup_ulcase(void)后通过调用/* create letters string */ n = 0; for (c = 0; c < 256; c++) { if (isalpha(c)) ul[n++] = c; } ulo = PyString_FromStringAndSize((const char *)ul, n); if (!ulo) return; if (string) PyDict_SetItemString(string, "letters", ulo); Py_DECREF(ulo); 来覆盖该模块,其中包含以下内容:

PyLocale_setlocale

反过来,这会在setlocale中调用,确实是getpreferredencoding,由 def getpreferredencoding(do_setlocale = True): """Return the charset that the user is likely using, according to the system configuration.""" if do_setlocale: oldloc = setlocale(LC_CTYPE) try: setlocale(LC_CTYPE, "") except Error: pass result = nl_langinfo(CODESET) setlocale(LC_CTYPE, oldloc) return result else: return nl_langinfo(CODESET) 调用 - 代码http://hg.python.org/cpython/file/07a6fca7ff42/Lib/locale.py#l612

getpreferredencoding(False)

我该如何避免呢?

尝试getdefaultlocale

为什么不在Windows中发生?

Windows使用不同的代码来获取区域设置,您可以看到here

在Python 3中

在Python 3中,{{1}}不接受布尔的setlocale变量,也不会调用setlocale本身,因为你可以看到here