注意:OP做什么来解决问题是将encoding =’UTF-8’传递给打开的调用。如果你遇到这个问题,只是寻找一个修复这个工作。其余的职位是强调为什么。
怎么了
正如卢卡斯所说,文件指明:
On some systems, it is necessary to invoke setlocale() to obtain the user preferences
最初,string.letters设置为返回小写大写:
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调用 – 这里的代码为http://hg.python.org/cpython/file/07a6fca7ff42/Lib/locale.py#l612:
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)
我该如何避免?
尝试getpreferredencoding(False)
为什么Windows不会发生?
Windows使用不同的代码获取区域设置,您可以看到here。
在Python 3中
在Python 3中,getdefaultlocale不接受布尔setlocale变量,并且不会像here那样调用setlocale本身。