【问题标题】:What exactly does Spyder do to Unicode strings?Spyder 究竟对 Unicode 字符串做了什么?
【发布时间】:2014-10-11 07:54:19
【问题描述】:

在 Ubuntu 14.04 上的标准 GNU 终端模拟器中运行 Python,我在交互输入时得到了预期的行为:

>>> len('tiθ')
4
>>> len(u'tiθ')
3

在 Spyder 中运行显式 utf8 编码的脚本时也会发生同样的情况:

# -*- coding: utf-8 -*-
print(len('tiθ'))
print(len(u'tiθ'))

...给出以下输出,无论我是在新的专用解释器中运行它,还是在 Spyder 默认解释器中运行(如图所示):

>>> runfile('/home/dan/Desktop/mwe.py', wdir=r'/home/dan/Desktop')
4
3

但是当在 Spyder 中的 Python 控制台中以交互方式输入时:

>>> len('tiθ')
4
>>> len(u'tiθ')
4

elsewhere 提出了这个问题,但这个问题涉及 Windows 和 Linux 之间的差异。在这里,我在同一系统上的不同控制台中得到不同的结果,并且终端模拟器和 Spyder 控制台中的 Python 启动消息是相同的:

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

这里发生了什么,我怎样才能让 Python-within-Spyder 在 unicode 字符串方面表现得像 Python-in-the-shell? @martijn-pieters 对 this question 发表评论

Spyder 做了各种各样的事情来破坏 Python 环境的正常运行。

但我希望有一种方法可以解除此特定功能的破坏,因为当我不能依赖交互式键入命令产生与脚本运行相同的结果时,在 IDE 中调试脚本变得非常困难作为一个整体与他们的coding: utf-8 声明。

更新

在 GNU 终端中:

>>> repr(u'tiθ')
"u'ti\\u03b8'"
>>> import sys
>>> sys.stdin.encoding
'UTF-8'
>>> sys.getdefaultencoding()
'ascii'

在 Spyder 控制台中:

>>> repr(u'tiθ')
"u'ti\\xce\\xb8'"
>>> import sys
>>> sys.stdin.encoding  # returns None
>>> sys.getdefaultencoding()
'UTF-8'

知道了这一点,我可以说服 Spyder 像 GNU 终端一样工作吗?

【问题讨论】:

  • repr(u'tiθ') 产生什么?这里的问题在于该控制台的 input 设置。您的键盘输入生成字节,而不是源文件,供 Python 解码为 Unicode 文本。
  • 在交互式控制台中,您似乎正在使用 UTF-8 终端,Python 可以检测到这一点,因此 u'tiθ' 可以正常工作;然后字节不会从常规文件中读取,而是从终端环境中读取。
  • @MartijnPieters 查看更新回复:repr()的结果
  • 您的键盘正在生成 UTF-8(repr('tiθ') 将以字节为单位匹配)但 Spyder 认为它是 Latin-1(或 CP-1252,但您使用的是 Linux,而不是 Windows,因此可能性较小)。不知道如何配置控制台来改变它。 import sys; sys.stdin.encoding 很可能会确认这一点。
  • @CarlosCordoba:首先拨打sys.setdefaultencoding() 电话;这与输入和输出无关,但确实掩盖了人们依赖隐式编码/解码的代码中的错误。接下来,您必须研究如何使用与 GUI 输入源相同的编码为您的控制台打开 sys.stdin;不过,这不是我能帮忙的。也许 PyCharm 社区版代码库提供了他们如何解决这个问题的线索。

标签: python unicode spyder


【解决方案1】:

经过一番研究,似乎这种奇怪的行为至少部分内置于 Python 中(参见 this discussion thread;简单地说,Python 将 sys.stdin.encoding 设置为 None 作为默认值,并且只有在检测到时才会更改它主机是tty,它可以检测到tty的编码)。

也就是说,一个骇人听闻的解决方法就是告诉 Spyder 使用 /usr/bin/python3 作为其可执行文件,而不是默认值(即 Python 2.7.6)。在 Spyder 或 GNU 终端模拟器中运行 Python 3 控制台时,我得到的结果与以前不同(更好!),但重要的是结果是一致的,无论是运行脚本还是交互输入,也不管使用 GNU 终端还是Spyder 控制台:

>>> len('tiθ')
3
>>> len(u'tiθ')
3
>>> import sys
>>> sys.stdin.encoding
'UTF-8'
>>> sys.getdefaultencoding()
'utf-8'

然而,这会导致 Spyder 中的其他问题:例如,它的 sitecustomize.py 脚本对 Python 3 不友好,因此每个新的解释器都以

开头
Error in sitecustomize; set PYTHONVERBOSE for traceback:
SyntaxError: invalid syntax (sitecustomize.py, line 432)

无论如何,口译员似乎工作得很好,但这让我很紧张,我不认为这是一个“可接受”的答案,所以如果其他人有更好的主意......

【讨论】:

  • 你的 Spyder 版本是多少?如果小于2.3.0,则需要更新。这是第一个与 Python 3 兼容的版本。我之所以这么说,是因为在我们的 sitecustomize.py 的当前 432 行中我没有看到任何奇怪的东西
  • 我检查了我们的 2.2 系列的 sitecustomize,现在我几乎可以肯定你需要更新 :)
  • 在 Python 3 中,u 前缀没有任何意义。 u'tiθ''tiθ'完全相同。但是 Python 3 使用的默认编码是 UTF-8,所以这对你的情况很有帮助。
  • @MartijnPieters:是的,我知道 Python 3 中的所有字符串都是 unicode 字符串;我只是有点懒惰,因为我从早期的测试中复制粘贴。
  • @CarlosCordoba:很高兴知道 2.3+ 与 Py3 兼容;我在2.2.5。但是对于它的价值,如果在 Py2 下也能按预期工作,那将是真的很好。
猜你喜欢
  • 2012-07-23
  • 2016-09-10
  • 2023-03-15
  • 2012-10-17
  • 2021-06-04
  • 1970-01-01
  • 2018-07-30
  • 2019-10-06
  • 2021-01-01
相关资源
最近更新 更多