使用compile函数时出现UnicodeEncodeError

5 投票
3 回答
7989 浏览
提问于 2025-04-17 09:54

在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 个回答

0

我觉得你可以试着把文件路径中的反斜杠“\”换成斜杠“/”,就像这样:

compile('pass', r'c:\temp\工具\module1.py', 'exec')

compile('pass', r'c:/temp/工具/module1.py', 'exec')

我也遇到过和你一样的问题,我用这个方法解决了。希望这个方法对你也有用。

1

这里有一个对我有效的解决方案:问题 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 !
5

根据Python的第10114号问题,看起来Python的逻辑是,所有使用的文件名都应该在它们被使用的平台上是有效的。这些文件名是通过文件系统编码来处理的,这个编码在Python的C语言内部使用。

我同意在Windows上可能不应该报错,因为任何Unicode文件名都是有效的。你可以考虑向Python提交一个bug报告。不过要注意,所需的修改可能并不简单,因为任何使用文件名的C代码都需要处理无法编码的情况。

撰写回答