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

时间:2014-01-04 16:39:19

标签: python encoding python-3.2

我正在使用剪辑字符(9986 - ✂)的Python脚本,我正在尝试将代码移植到Mac,但我遇到了这个错误。

剪刀角色在从IDLE(Python 3.2.5 - OS X 10.4.11 iBook G4 PPC)运行时显示正常,并且代码在Ubuntu 13.10上运行完全正常,但当我尝试在终端中运行时我得到这个错误/追溯:

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|")

这是否表示终端无法显示该字符?我知道这是一个旧系统,但它是我目前唯一使用的系统。操作系统的年龄是否会干扰该计划?

我已经阅读了这些问题:

导致此错误的原因是什么?它是系统/操作系统的时代,Python的版本,还是一些编程错误?

修改: 这个错误随后会出现这个重复的问题(我以为我会添加它,因为它在同一个程序中并且是同样的错误):

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

编辑 Ran命令为@ J.F.塞巴斯蒂安问:

python3 test-io-encoding.py

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

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

编辑尝试@PauloBu提供的“黑客”解决方案:

正如你所看到的,这导致一个(Yay!)剪刀,但我现在得到一个新的错误。回溯/错误:

+-=============================-+
✂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修复的结果:

+-=============================-+
|
✂ PySnipt'd 
✂       |
+-=============================-+

修改

他修复了他的问题:

+-=============================-+
✂✂|       PySnipt'd     |
+-=============================-+

4 个答案:

答案 0 :(得分:21)

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

这意味着如果您的终端使用ascii作为编码,Python会尝试将scissor char编码为ascii。当然,ascii不支持它,因此您会收到Unicode解码错误。

这就是您必须明确编码输出的原因。明确比隐性记忆好吗?要修复您的代码,您可以这样做:

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

这看起来有点黑客。您还可以在执行脚本之前设置PYTHONIOENCODING = utf-8。我对两种解决方案感到不舒服。可能你的控制台不支持utf-8而且你看到了胡言乱语。但是你的程序运行正常。

如果肯定需要在控制台上显示正确的输出,我强烈建议您将控制台设置为使用另一种支持scissor字符的编码。 (也许是utf-8)。在Linux上,可以通过执行以下操作来实现:export lang=UTF_8。在Windows上,您可以使用chcp更改控制台的代码页。只需弄清楚如何在你的设置中设置utf8和恕我直言,这将是最好的解决方案。

<小时/> 您不能混用printsys.stdout.write,因为它们基本相同。关于你的代码,黑客的方式是这样的:

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

希望这有帮助!

答案 1 :(得分:16)

test_io_encoding.py输出表明您应更改locale设置,例如设置LANG=en_US.UTF-8


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

>>> 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运行脚本。您将获得:

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

否则会出现其他错误。

只需放弃.decode()来电:

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

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

$ 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环境变量:

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

  

终端只显示:| b'\xe2\x9c\x82' PySnipt'd b'\xe2\x9c\x82' |

如果snipperbytes个对象,请离开snipper.decode()个来电。

$ 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)

修复方法是一样的:

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

答案 2 :(得分:0)

我的语言环境设置为de_AT.UTF-8但/etc/profile中的这些行 失踪了:

export LANG=de_AT.UTF-8
export LANGUAGE=de_AT.UTF-8
export LC_ALL=de_AT.UTF-8

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

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

输出应该类似于:

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

答案 3 :(得分:-4)

在文件.py的第一行,您需要添加此字符串:

# - - 编码:utf-8 - -

你也可以试试这个:

print(“| \ t”,unichr(9986),“PySnipt'd”,unichr(9986),“\ t |”)