使用compile函数时出现UnicodeEncodeError
在Windows 7上使用Python 3.2时,我在IDLE中遇到了以下问题:
>>compile('pass', r'c:\temp\工具\module1.py', 'exec')
UnicodeEncodeError: 'mbcs' codec can't encode characters in position 0--1: invalid character
有没有人能解释一下为什么编译语句会尝试用mbcs来转换unicode文件名?我知道在Windows中,sys.getfilesystemencoding返回的是'mbcs',但我以为在提供unicode文件名时,这个设置是不会被使用的。
例如:
f = open(r'c:\temp\工具\module1.py')
这个是可以正常工作的。
为了进行更全面的测试,请将以下内容保存为utf8编码的文件,然后使用标准的python.exe版本3.2来运行它。
# -*- coding: utf8 -*-
fname = r'c:\temp\工具\module1.py'
# I do have the a file named fname but you can comment out the following two lines
f = open(fname)
print('ok')
cmp = compile('pass', fname, 'exec')
print(cmp)
输出:
ok
Traceback (most recent call last):
File "module8.py", line 6, in <module>
cmp = compile('pass', fname, 'exec')
UnicodeEncodeError: 'mbcs' codec can't encode characters in position 0--1: inval
id character
3 个回答
我觉得你可以试着把文件路径中的反斜杠“\”换成斜杠“/”,就像这样:
compile('pass', r'c:\temp\工具\module1.py', 'exec')
compile('pass', r'c:/temp/工具/module1.py', 'exec')
我也遇到过和你一样的问题,我用这个方法解决了。希望这个方法对你也有用。
这里有一个对我有效的解决方案:问题 427: UnicodeEncodeError: 'ascii' 编码无法编码位置 1-6 的字符: 序号不在范围内 (128):
如果你查看 PyScripter 的帮助文件,在“编码的 Python 源文件”这个主题下(最后一段),它会告诉你如何通过修改 site.py 文件来配置 Python,以支持其他编码。这个文件在 Python 安装目录的 lib 子目录下。找到 setencoding 这个函数,确保支持本地化的默认字符串编码是开启的。(见下文)
def setencoding():
"""Set the string encoding used by the Unicode implementation. The
default is 'ascii', but if you're willing to experiment, you can
change this."""
encoding = "ascii" # Default value set by _PyUnicode_Init()
if 0: <<<--- set this to 1 ---------------------------------
# Enable to support locale aware default string encodings.
import locale
loc = locale.getdefaultlocale ()
if loc[1]:
encoding = loc[1]
if 0:
# Enable to switch off string to Unicode coercion and implicit
# Unicode to string conversion.
encoding = "undefined"
if encoding != "ascii":
# On Non-Unicode builds this will raise an AttributeError...
sys.setdefaultencoding (encoding) # Needs Python Unicode
build !
根据Python的第10114号问题,看起来Python的逻辑是,所有使用的文件名都应该在它们被使用的平台上是有效的。这些文件名是通过文件系统编码来处理的,这个编码在Python的C语言内部使用。
我同意在Windows上可能不应该报错,因为任何Unicode文件名都是有效的。你可以考虑向Python提交一个bug报告。不过要注意,所需的修改可能并不简单,因为任何使用文件名的C代码都需要处理无法编码的情况。