关于python:UnicodeEncodeError:’ascii’编解码器无法对位置0中的字符进行编码:序号不在范围内(128)

UnicodeEncodeError: 'ascii' codec can't encode character in position 0: ordinal not in range(128)

我正在编写一个使用剪刀字符(9986-?)的python脚本。我正试图把我的代码移植到Mac,但我遇到了这个错误。

当从空闲(python 3.2.5-os x 10.4.11 ibook g4 ppc)运行时,剪刀字符显示得很好,代码在Ubuntu 13.10上完全正常工作,但当我尝试在终端中运行时,我会得到这个错误/回溯:

1
2
3
4
5
6
7
8
Traceback (most recent call last):
  File"snippets-convert.py", line 352, in <module>
    main()
  File"snippets-convert.py", line 41, in main
    menu()
  File"snippets-convert.py", line 47, in menu
    print ("|\t",snipper.decode(),"PySnipt'd",snipper.decode(),"\t|")
UnicodeEncodeError: 'ascii' codec can't encode character '\u2702' in position 0: ordinal not in range(128)

给我问题的代码是:

print ("|\t",chr(9986),"PySnipt'd",chr(9986),"\t|")

这不是表示终端没有能力显示该字符吗?我知道这是一个旧系统,但它是我目前唯一必须使用的系统。操作系统的年龄会影响程序吗?

我读过这些问题:

  • unicodeencodeerror:"ascii"编解码器无法对位置0中的字符u'xef'进行编码:序号不在范围(128)内-不同的字符

  • "unicodeencodeerror:'ascii'编解码器无法对字符进行编码"-使用2.6,因此不知道它是否适用

  • unicodeencodeerror:"ascii"编解码器无法编码字符?-似乎是解决我的问题的一个合理的方法,.encode('UTF-8'),我不明白这个错误。但是,它显示的是字符代码,而不是我想要的字符,而.decode()只是给出了相同的错误。不确定我是否做得对。

  • unicodeencodeerror:"ascii"编解码器无法对位置0-6中的字符进行编码:序号不在范围(128)内-不确定这是否适用,他使用的是一个GUI,正在获取输入,全部是希腊语。

是什么导致了这个错误?这是系统/OS的时代、Python的版本还是一些编程错误?

编辑:这个错误稍后会出现在这个重复的问题上(只是认为我会添加它,因为它在同一个程序中,并且是相同的错误):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Traceback (most recent call last):
  File"snippets-convert.py", line 353, in <module>
    main()
  File"snippets-convert.py", line 41, in main
    menu()
  File"snippets-convert.py", line 75, in menu
    main()
  File"snippets-convert.py", line 41, in main
    menu()
  File"snippets-convert.py", line 62, in menu
    search()
  File"snippets-convert.py", line 229, in search
    print_results(search_returned)      # Print the results for the user
  File"snippets-convert.py", line 287, in print_results
    getPath(toRead)                                             # Get the path for the snippet
  File"snippets-convert.py", line 324, in getPath
    snipXMLParse(path)
  File"snippets-convert.py", line 344, in snipXMLParse
    print (chr(164),child.text)
UnicodeEncodeError: 'ascii' codec can't encode character '\xa4' in position 0: ordinal not in range(128)

编辑:

我进入终端字符设置,它实际上支持该字符(如您在屏幕截图中看到的那样:

enter image description here

当我把它插入终端时,它打印出这个:\342\234\202,当我按下enter时,我得到这个:-bash: ?: command not found

按@J.F.Sebastian的要求编辑运行的命令:

python3 test-io-encoding.py

1
2
3
4
5
6
7
8
9
10
PYTHONIOENCODING:       None
locale(False):  US-ASCII
device(stdout): US-ASCII
stdout.encoding:        US-ASCII
device(stderr): US-ASCII
stderr.encoding:        US-ASCII
device(stdin):  US-ASCII
stdin.encoding: US-ASCII
locale(False):  US-ASCII
locale(True):   US-ASCII

python3 -S test-io-encoding.py

1
2
3
4
5
6
7
8
9
10
PYTHONIOENCODING:       None
locale(False):  US-ASCII
device(stdout): US-ASCII
stdout.encoding:        US-ASCII
device(stderr): US-ASCII
stderr.encoding:        US-ASCII
device(stdin):  US-ASCII
stdin.encoding: US-ASCII
locale(False):  US-ASCII
locale(True):   US-ASCII

edit尝试了@paulobu提供的"黑客"解决方案:

如你所见,这导致了一个(耶!)剪刀,但我现在有一个新的错误。回溯/错误:

1
2
3
4
5
6
7
8
9
+-=============================-+
?Traceback (most recent call last):
  File"snippets-convert.py", line 357, in <module>
    main()
  File"snippets-convert.py", line 44, in main
    menu()
  File"snippets-convert.py", line 52, in menu
    print("|\t"+sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" PySnipt'd"+ sys.stdout.buffer.write(chr(9986).encode('UTF-8'))+" \t|")
TypeError: Can't convert 'int' object to str implicitly

编辑@paulobu修复的添加结果:

1
2
3
4
5
+-=============================-+
|
? PySnipt'd
?       |
+-=============================-+

编辑:

他的解决方法是:

1
2
3
+-=============================-+
??|       PySnipt'd     |
+-=============================-+


当python打印并输出时,它会自动将其编码到目标介质。如果它是一个文件,utf-8将被用作默认值,每个人都会很高兴,但是如果它是一个终端,python将找出终端使用的编码,并尝试使用该编码对输出进行编码。

这意味着,如果终端使用ascii作为编码,那么python将尝试将scissor字符编码为ascii。当然,ASCII不支持它,所以会出现Unicode解码错误。

这就是为什么您总是必须显式地对输出进行编码。显性优于隐性记得吗?要修复代码,可以执行以下操作:

1
2
import sys
sys.stdout.buffer.write(chr(9986).encode('utf8'))

这似乎有点黑客。在执行脚本之前,还可以设置pythoniencoding=utf-8。我对这两种解决方案都不满意。可能你的控制台不支持UTF-8,你会看到胡言乱语。但是你的程序会正常运行。

如果您确实需要在控制台上显示正确的输出,我强烈建议您将控制台设置为使用另一种编码,即支持scissor字符的编码。(可能是UTF-8)。在Linux上,可以通过这样做来实现:export lang=UTF_8。在Windows上,您可以使用chcp更改控制台的代码页。只需找出如何在您的和imho中设置utf8,这将是最好的解决方案。

你不能混合使用printsys.stdout.write,因为它们基本上是相同的。关于您的代码,黑客的方式如下:

1
sys.stdout.buffer.write(("|\t"+ chr(9986) +" PySnipt'd" + chr(9986)+" \t|").encode('utf8'))

我建议你读一下文档,看看在print函数和sys.stdout函数下发生了什么:http://docs.python.org/3/library/sys.html sys.stdin

希望这有帮助!


test_io_encoding.py输出建议您更改locale设置,如设置LANG=en_US.UTF-8

第一个错误可能是由于您试图解码已经是Unicode的字符串。python 2尝试使用默认字符编码('ascii')对其进行编码,然后使用(可能)不同的字符编码对其进行解码。错误发生在encode步骤:

1
2
3
4
>>> u"\u2702".decode() # Python 2
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2702' in position 0: ordinal not in range(128)

看起来您正在使用python 2而不是python 3运行脚本。你会得到:

1
2
3
4
>>>"\u2702".decode() # Python 3
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'

不同的错误。

放下.decode()电话:

1
print("|\t {0} PySnipt'd {0} \t|".format(snipper))

第二个问题是将Unicode字符串打印到管道中:

1
2
3
4
5
6
$ python3 -c'print("\u2702")'
?
$ python3 -c'print("\u2702")' | cat
Traceback (most recent call last):
  File"<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2702' in position 0: ordinal not in range(128)

设置适合您的目的的PYTHONIOENCODING环境变量:

1
2
$ PYTHONIOENCODING=utf-8 python3 -c'print("\u2702")' | cat
?

the terminal is just displaying this: | b'\xe2\x9c\x82' PySnipt'd b'\xe2\x9c\x82' |

如果snipperbytes对象,则保留snipper.decode()调用。

1
2
3
4
5
6
$ python3 -c"print(b'\xe2\x9c\x82'.decode())"
?
$ python3 -c"print(b'\xe2\x9c\x82'.decode())" | cat
Traceback (most recent call last):
  File"<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2702' in position 0: ordinal not in range(128)

修复方法相同:

1
2
$ PYTHONIOENCODING=utf-8 python3 -c"print(b'\xe2\x9c\x82'.decode())" | cat
?


我的区域设置为de_at.utf-8,但这些行在/etc/profile中失踪:

1
2
3
export LANG=de_AT.UTF-8
export LANGUAGE=de_AT.UTF-8
export LC_ALL=de_AT.UTF-8

注销/登录,您的问题应该得到解决

要验证所有区域设置是否正确,请在终端中键入locale

输出应与此类似:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LANG=de_AT.UTF-8
LANGUAGE=de_AT.UTF-8
LC_CTYPE="de_AT.UTF-8"
LC_NUMERIC="de_AT.UTF-8"
LC_TIME="de_AT.UTF-8"
LC_COLLATE="de_AT.UTF-8"
LC_MONETARY="de_AT.UTF-8"
LC_MESSAGES="de_AT.UTF-8"
LC_PAPER="de_AT.UTF-8"
LC_NAME="de_AT.UTF-8"
LC_ADDRESS="de_AT.UTF-8"
LC_TELEPHONE="de_AT.UTF-8"
LC_MEASUREMENT="de_AT.UTF-8"
LC_IDENTIFICATION="de_AT.UTF-8"
LC_ALL=de_AT.UTF-8

在文件的第一行.py中,需要添加以下字符串:

#--编码:UTF-8--

你也可以试试这个:

打印(" ",unichr(9986),"pysnipt'd",unichr(9986)," "