我正在使用一个使用剪刀字符(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|")
这是否表示终端无法显示该字符?我知道这是一个旧系统,但它是我目前唯一使用的系统 . 操作系统的时代是否会干扰该计划?
我读过这些问题:
-
"UnicodeEncodeError: 'ascii' codec can't encode character" - 使用2.6,所以不知道它是否适用
-
UnicodeEncodeError: 'ascii' codec can't encode character? - 似乎是我问题的合理解决方案,
.encode('UTF-8')
,我没有收到错误 . 但是,它显示的是字符代码,而不是我想要的字符,.decode()
只是给了我同样的错误 . 不确定我是否正确行事 . -
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-6: ordinal not in range(128) - 不确定这是否适用,他正在使用GUI,获取输入,所有都是希腊语 .
是什么导致了这个错误?它是系统/操作系统的时代,Python的版本,还是一些编程错误?
EDIT :此错误随后会出现这个重复的问题(我以为我会添加它,因为它在同一个程序中并且是同样的错误):
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)
EDIT:
我进入了终端字符设置,它实际上支持该字符(正如您在此屏幕截图中看到的那样:
当我将它插入终端时它打印出来: \342\234\202
当我按Enter键时我得到这个: -bash: ✂: command not found
EDIT 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
EDIT 试过@PauloBu提供的"hackerish"解决方案:
正如你所看到的,这导致了一个(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
EDIT 添加了@ PauloBu修复的结果:
+-=============================-+
|
✂ PySnipt'd
✂ |
+-=============================-+
EDIT :
他修复了他的问题:
+-=============================-+
✂✂| PySnipt'd |
+-=============================-+
4 回答
当Python打印输出时,它会自动将其编码为目标介质 . 如果它是一个文件,UTF-8将被用作默认值,每个人都会很高兴,但如果它是终端,Python会找出终端正在使用的编码,并尝试使用该编码对输出进行编码 .
这意味着如果您的终端使用
ascii
作为编码,Python正在尝试将scissor
char编码为ascii . 当然,ascii不支持它,因此您会收到Unicode解码错误 .这就是为什么 you always have to explicitly encode your output . 明确比隐性记忆好吗?要修复代码,您可以执行以下操作:
这看起来有点黑客 . 您还可以在执行脚本之前设置PYTHONIOENCODING = utf-8 . 我对两种解决方案感到不舒服 . 可能你的控制台不支持utf-8而且你看到了胡言乱语 . 但是你的程序行为正常 .
如果您需要在控制台上显示正确的输出,我强烈建议您将控制台设置为使用另一种支持
scissor
字符的编码 . (也许是utf-8) . 在Linux上,可以通过以下方式实现:export lang=UTF_8
. 在Windows上,您可以使用chcp
更改控制台的代码页 . 只是弄清楚如何在你的设置和恕我直言,这将是最好的解决方案 .你不能混合
print
和sys.stdout.write
,因为它们基本相同 . 关于你的代码,黑客的方式是这样的:我建议你阅读文档,看看
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
步骤:看起来您正在使用Python 2而不是Python 3运行脚本 . 您将获得:
否则会出现其他错
只需删除
.decode()
电话:第二个问题是由于将Unicode字符串打印到管道中:
设置适合您的目的
PYTHONIOENCODING
环境变量:如果
snipper
是bytes
对象,则保留snipper.decode()
调用 .修复是一样的:
我的语言环境设置为de_AT.UTF-8但
/etc/profile
中的这些行丢失了:注销/登录,你的问题应该解决
要验证是否正确设置了所有语言环境,请在终端中键入
locale
输出应该类似于:
在文件.py的第一行中,您需要添加此字符串,:
# - 编码:utf-8 -
你也可以尝试这个:
print(“| \ t”,unichr(9986),“PySnipt'd”,unichr(9986),“\ t |”)