【问题标题】:python 2.7 ignores default encoding set in sitecustomize.py when parsing scriptspython 2.7 在解析脚本时忽略 sitecustomize.py 中设置的默认编码
【发布时间】:2014-11-07 00:14:10
【问题描述】:

我在让 python 2.7 读取包含 utf-8 字符串的脚本时遇到问题;在 sitecustomize.py 中将默认编码设置为 utf-8 似乎不需要。

这是我的 sitecustomize.py:

import sys
sys.setdefaultencoding("utf-8")

我可以从命令行验证默认编码是否已更改:

$ /usr/bin/python -c 'import sys; print(sys.getdefaultencoding())'
utf-8

但是,当我尝试运行包含 utf-8 字符串的脚本时,如下面的 test.py 中(在代码点 U+00b7 处包含·)...

filename = 'utf-8·filename.txt'
print(filename)

…默认编码似乎被忽略了:

$ /usr/bin/python test.py 
  File "test.py", line 1
SyntaxError: Non-ASCII character '\xc2' in file test.py on line 1, but
no encoding declared; see http://www.python.org/peps/pep-0263.html for details

使用encoding declaration,如下面的test-coding.py...

# coding=utf-8
filename = 'utf-8·filename.txt'
print(filename)

确实工作:

$ /usr/bin/python test-coding.py
utf-8·filename.txt

不幸的是,问题出在由另一个程序(catkin 构建系统的 catkin_make)生成和运行的脚本上。在 catkin_make 运行它们之前,我无法手动将编码声明添加到这些脚本中,从而给出 SyntaxError & check PEP 263。更改默认编码似乎是唯一没有深入了解 catkin 的解决方案,或者消除我系统上的所有非 ascii 路径……并且在 sitecustomize.py 中设置它应该可以工作,但不会。

非常感谢任何想法或见解!

【问题讨论】:

  • 你为什么要设置默认编码根本。你不应该那样做。相反,请修复您的 Unicode 处理代码,使其不依赖默认编码。
  • 此外,系统默认编码从不用于源文件。这是硬编码的默认值。
  • 我宁愿使用编码声明,但脚本是由另一个程序(catkin 构建系统的 catkin_make)生成和运行的。在 catkin_make 运行它们之前,我无法手动将编码声明添加到这些脚本中。

标签: python python-2.7 encoding utf-8


【解决方案1】:

sys.setdefaultencoding("utf-8") 没有做你认为它正在做的事情。它对 Python 解析源文件的方式没有影响。这就是为什么当源文件使用非 ascii 字符时仍然会看到 SyntaxErrors 的原因。要消除这些错误,您需要在源文件的开头添加编码声明,例如

# -*- encoding: utf-8 -*-

关于sys.setdefaultencoding

不要尝试更改默认编码。 Python 在 str 之间进行静默转换时使用默认编码 和统一码。例如,

预期的 Python2 行为:

In [1]: '€' + u'€'

应该引发 UnicodeDecodeError 因为 Python 尝试通过以下方式将 '€' 转换为 unicode 计算'€'.decode(sys.getdefaultencoding())

如果您更改默认编码,您会得到不同的行为:

In [2]: import sys; reload(sys); sys.setdefaultencoding('utf-8')
<module 'sys' (built-in)>

In [3]: '€' + u'€'
u'\u20ac\xe2\x82\xac'

如果您更改默认编码,那么您的 Python 行为将与几乎所有其他人对 Python2 应该如何行为的预期不同。

【讨论】:

  • 你是对的,我宁愿将编码声明放在文件中,但脚本正在生成并立即被另一个程序 catkin_make 使用。如果没有破解我自己的 catkin_make 版本,我无法在脚本无法运行之前将其放入其中。
  • 这是similar bug report。我认为您可能需要与 catkin 开发人员讨论您的问题,以便干净利落地解决它(无需破解 catkin)。
【解决方案2】:

您不能为源文件设置默认编码。该默认设置是硬编码的,作为语言规范的一部分。

请改为设置 PEP 263 标头,因为解释器会指示您这样做。您必须修复 Catkin 构建系统,或重写它生成的文件以包含标头。只需使用 # coding=utf8 在这些文件中添加第一行或第二行,使用 Python 即可轻松完成这项任务。

系统默认编码用于运行代码中Unicode和字节串对象的隐式编码和解码。您不应该尝试更改它,因为其他人通常依赖于不更改的值。设置它的功能已从 Python 3 中完全删除。

【讨论】:

  • 听起来没有办法隐含地说“像他们说的那样对待所有文件 #coding=utf8”,这是一种耻辱。谢谢!
  • @HonoreDoktorr Python 3 会这样做,但这也需要更改语法。
猜你喜欢
  • 2014-06-19
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多