python raw_input带有包含字符串的重音的奇怪行为

我正在编写一个程序,要求用户输入包含重音的输入.测试用户输入字符串以查看它是否与程序中声明的字符串匹配.如下所示,我的代码不起作用:

# -*- coding: utf-8 -*-

testList = ['má']
myInput = raw_input('enter something here: ')

print myInput, repr(myInput)
print testList[0], repr(testList[0])
print myInput in testList

使用pydev在eclipse中输出

enter something here: má
m√° 'm\xe2\x88\x9a\xc2\xb0'
má 'm\xc3\xa1'
False

IDLE输出

enter something here: má
má u'm\xe1'
má 'm\xc3\xa1'

Warning (from warnings module):
  File "/Users/ryanculkin/Desktop/delete.py", line 8
    print myInput in testList
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
False

在比较两个字符串时,如何让我的代码打印出True?

另外,我注意到在同一输入上运行此代码的结果是不同的,这取决于我是使用eclipse还是IDLE.为什么是这样?我的最终目标是将我的程序放在网上;有什么我需要注意的,因为结果似乎是如此不稳定吗?

最佳答案
您遇到的是raw_input为您提供了一个字节字符串,但您要比较的字符串是一个Unicode字符串. Python 2尝试将它们转换为要比较的公共类型,但是这会失败,因为它无法猜测字节字符串的编码 – 因此,您的解决方案是明确地进行转换.

作为一项规则,您应该将程序中的所有字符串作为unicode字符串浮动 – 您以字节形式读取的任何内容都会立即转换为unicode;你在程序中作为文字的任何东西,使它成为unicode文字,除非由于某种原因显然需要是一个字节串.这导致了unicode sandwich,这通常会让您的生活更轻松.

对于文字,你要么想要将你的字符串声明为u’má’,要么:

from __future__ import unicode_literals

在脚本顶部附近制作’未加前缀的字符串’unicode.你得到的错误意味着你已经完成了这一点.

要读取unicode字符串,您需要意识到raw_input为您提供了一个字节字符串 – 因此,您需要使用其.decode方法进行转换.你需要传递.decode你的STDIN的编码 – 它可以作为sys.stdin.encoding(不要只是假设这是UTF8 – 它通常是,但并不总是) – 所以,整行将是:

string = raw_input(...).decode(sys.stdin.encoding) 

但到目前为止最简单的方法是升级到Python 3,如果可以的话 – 那里,input()(其行为类似于Py2 raw_input)会给你一个unicode字符串(它为你调用.decode,所以你没有记住它,默认情况下,无前缀字符串是unicode字符串.这使得使用重音字符更加容易 – 这实际上意味着您尝试的逻辑只能在Py3中工作,因为它做了正确的事情.

但请注意,您看到的错误仍会在Py3中显示 – 但由于它默认情况下做的是正确的,所以您必须努力工作才能遇到它.但是,如果你这样做,比较只会是False,没有任何警告 – Py3不会试图在字节和unicode字符串之间进行隐含转换,因此任何字节字符串将始终与任何unicode字符串进行比较,并且尝试对它们进行排序将抛出一个例外.

转载注明原文:python raw_input带有包含字符串的重音的奇怪行为 - 代码日志