【问题标题】:JSON in Python: encoding issue on OS X, no issue on WindowsPython 中的 JSON:OS X 上的编码问题,Windows 上没有问题
【发布时间】:2015-06-17 04:13:38
【问题描述】:

我有一个文件log.json,其中包含一行:

{"k":"caf\u00e9"}

我在 Windows 7 SP1 x64 Ultimate 上运行以下代码:

import json 
a = json.load(open('log.json', 'r'))
f = open('test.txt', 'w')
f.write(a['k'])

我没有任何问题。

当我在 Max OS X 10.10 x64 上运行相同的代码时:

Traceback (most recent call last):
  File "/Users/francky/Documents/workspace/test.py", line 4, in <module>
    f.write(a['k'])
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 3: ordinal not in range(128)

为什么它在 Windows 上运行良好,但在 OS X 上却不行?


Python 解释器和 JSON Python 包的版本在两个操作系统上是相同的:

import json 
import sys
print json.__version__
print(sys.version)

在 OS X 上返回:

2.0.9
2.7.6 (default, Sep  9 2014, 15:04:36) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)]

在 Windows 上:

2.0.9
2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)]

罪魁祸首是 PyDev,used to use the Eclipse workspace or project setting "Text file encoding" and sets this as the Python default encoding(在 PyDev 3.4.0 及更高版本中修复)。

为了支持一些非 ASCII 字符,我将 Python 文件切换为 UTF-8:

导致 Python 的 sys.getdefaultencoding() 变为 UTF-8

仅供参考:Dangers of sys.setdefaultencoding('utf-8')

【问题讨论】:

  • 当你输入 print(sys.getdefaultencoding()) 时你会得到什么?可能在 os x 上它是默认的“ascii”,但不确定它在 Windows 上的工作原理是什么
  • afaik,os x 正在做“正确”的事情;这是因为您要求将无法使用 ascii 编解码器编码的 unicode 写入磁盘(当您未指定编码时,它使用系统默认编解码器)...您想使用类似 f.write(a['k'].encode('utf8'))
  • @lemonhead 谢谢,print(sys.getdefaultencoding()) 在两台计算机上输出ascii。确实 .encode('utf8') 解决了这个问题,但知道为什么 Windows 可以很好地处理它吗?
  • 嗯,是的,不确定,但本节可能会说明一些事情:docs.python.org/2/howto/unicode.html#unicode-filenames
  • hmm 看起来我在 Windows 上的 Eclipse 正在将 sys.getdefaultencoding() 修改为 UTF-8(与 Mac 上的 Eclipse 不同)。我在 Eclipse 之外运行了print(sys.getdefaultencoding()),这是个坏主意。谜团解开了,谢谢!

标签: python json windows macos encoding


【解决方案1】:

我在 Windows 上遇到了您的 OSX 故障,它应该失败,因为将 Unicode 字符串写入文件需要编码。当您将 Unicode 字符串写入文件时,Python 2 将使用默认的 ascii 编解码器将其隐式转换为字节字符串,并且对于非 ASCII 字符会失败。你确定你运行的是 Python 2.7 吗? Python 3 没有给出错误。 io.open 是 Python 2 上 open 的 Python 3 等价物,默认使用 sys.getfilesystemencoding()。以下是修复 Python 2 的方法:

import json
import io
data = r'{"k":"caf\u00e9"}'
a = json.loads(data)
with io.open('test.txt','w') as f:
    f.write(a['k'])

您可以选择为输出指定所需的确切编码作为附加参数:

with io.open('test.txt','w',encoding='utf8') as f:

【讨论】:

  • 谢谢,是的,我使用的是 Python 2.7。
  • 我也在运行 Windows 7 SP1 x64...它应该失败。您的设置有些不同...
  • hmm 看起来我在 Windows 上的 Eclipse 正在将 sys.getdefaultencoding() 修改为 UTF-8(与 Mac 上的 Eclipse 不同)。谜团解开了,谢谢!
  • 我称之为错误。更改默认编码可能会破坏假定默认值不变的模块。不建议这样做。 Python 甚至禁用了sys.setdefaultencoding()
猜你喜欢
  • 2013-02-19
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多