为什么我的Python程序获得的UnicodeDecodeError中的IntelliJ但确定在命令

2019-09-22 10:03发布

我有一个加载其中包含一个有趣的字符以.json文件的简单程序。 该方案(见下文),在终端运行正常,但得到的IntelliJ此错误:

UnicodeDecodeError错误:在位置2“ASCII”编解码器不能解码字节0xe2:顺序不在范围内(128)

关键的代码是:

with open(jsonFileName) as f:
    jsonData = json.load(f)

如果我更换了与开放:

with open(jsonFileName, encoding='utf-8') as f:

然后,它工作在两个的IntelliJ和终端。 我还是新来的Python和插件的IntelliJ,我不明白为什么它们是不同的。 我想sys.path可能会有所不同,但输出让我觉得这不是原因。 可能有人请解释一下吗? 谢谢!

版本:

  • 操作系统:Mac OS X 10.7.4(也10.6.8测试)
  • 蟒3.2.3(V3.2.3:3d0686d90f55,2012年4月10日,十一点25分50秒)/Library/Frameworks/Python.framework/Versions/3.2/bin/python3.2
  • 的IntelliJ:11.1.3终极

文件(2):

1. unicode-error-demo.py

#!/usr/bin/python

import json
from pprint import pprint as pp
import sys

def main():
    if len(sys.argv) is not 2:
        print(sys.argv[0], "takes one arg: a .json file")
        return

    jsonFileName = sys.argv[1]
    print("sys.path:")
    pp(sys.path)
    print("processing", jsonFileName)

#    with open(jsonFileName) as f:           # OK in Terminal, but BUG in IntelliJ: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 2: ordinal not in range(128)
    with open(jsonFileName, encoding='utf-8') as f:     # OK in both
        jsonData = json.load(f)
        pp(jsonData)


if __name__ == "__main__":
    main()

2.编码-temp.json

["™"]

Answer 1:

的JSON .load()函数需要Unicode数据,而不是原始字节。 Python的自动尝试字节串Unicode字符串你使用默认的编解码器(在你的情况ASCII)进行解码,和失败。 通过与打开文件UTF-8编码解码器,Python的让你一个明确的转换。 见open()函数 ,其中规定:

在文本模式下,如果没有指定编码中使用的编码是依赖于平台。

将用于确定如下编码:

  • 尝试os.device_encoding()以查看是否有一个终端的编码。
  • 使用locale.getpreferredencoding()函数 ,这取决于你运行你的代码的环境。在do_setlocale该功能被设置为False
  • 使用'ASCII' ,仿佛这两种方法都返回默认None

这是用C全部完成,但它的蟒蛇相当于将是:

if encoding is None:
    encoding = os.device_encoding()
if encoding is None:
    encoding = locale.getpreferredencoding(False)
if encoding is None:
    encoding = 'ASCII'

所以,当你在终端运行程序, os.deviceencoding()返回'UTF-8' ,但的IntelliJ下运行时,没有终端,如果没有区域设置要么,Python使用'ASCII'

在Python的Unicode指南会告诉你所有关于Unicode字符串和字节串,以及编码之间的差异。 关于这个问题的另一个重要文章是乔尔斯波斯基的绝对最低Unicode的知识文章 。



Answer 2:

的Python 2.x中有字符串和Unicode字符串。 基本字符串编码为ASCII。 ASCII仅使用7位/炭,其允许编码128个字符,而现代UTF-8使用多达4个字节/炭。 UTF-8是兼容ASCII(这样任何ASCII编码的字符串是一个有效的UTF-8字符串),而不是倒过来。

显然,你的文件名中包含非ASCII字符。 和Python默认希望在以简单的ASCII编码字符串读它,发现一个非ASCII字符(它的第一位不为0,因为它是0xe2),并说,“ASCII”编解码器不能在位置2解码字节0xe2:序数不在范围内(128)。

无关与Python,但还是我最喜欢的教程的编码:

http://hektor.umcs.lublin.pl/~mikosmul/computing/articles/linux-unicode.html



文章来源: Why does my Python program get UnicodeDecodeError in IntelliJ but is OK from the command line?