3

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


代码

# -*- 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。为什么是这样?我的最终目标是将我的程序放到网上;有什么我需要注意的吗,因为结果似乎如此不稳定?

4

3 回答 3

9

您遇到的是raw_input给您一个字节字符串,但您要比较的字符串是一个 Unicode 字符串。Python 2 尝试将它们转换为通用类型以进行比较,但这失败了,因为它无法猜测字节字符串的编码 - 因此,您的解决方案是显式地进行转换。

通常,您应该将程序中的所有字符串作为 unicode 字符串保持浮动 - 您以字节形式读取的任何内容都会立即转换为 unicode;您在程序中作为文字的任何内容,都将其设为 unicode 文字,除非它出于某种原因明确需要成为字节串。这导致了unicode 三明治,这通常会让你的生活更轻松。

对于文字,您要么希望将字符串声明为u'má',要么具有:

from __future__ import unicode_literals

靠近脚本顶部以制作'un-prefixed strings'unicode。您得到的错误意味着您已经完成了这一点。

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

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

但是到目前为止,最简单的解决方法是如果可以的话升级到 Python 3 - 那里input()(它的行为类似于 Py2raw_input否则)给你一个 unicode 字符串(它需要.decode你,所以你不必记住它),并且默认情况下,无前缀字符串是 unicode 字符串。这一切都使得处理重音字符变得更容易——它本质上意味着你尝试的逻辑只能在 Py3 中工作,因为它做了正确的事情。

但是请注意,您看到的错误仍然会出现在 Py3 中 - 但由于默认情况下它会做正确的事情,因此您必须努力工作才能遇到它。但如果你这样做了,比较只会是 False,没有警告 - Py3 不会尝试在字节字符串和 unicode 字符串之间进行隐式转换,因此任何字节字符串将始终与任何 unicode 字符串进行比较,并尝试对它们进行排序抛出异常。

于 2012-06-17T04:06:36.350 回答
0

请注意,您与 IDLE 与 PyDev 有所不同,因为 PyDev 会将 PYTHONIOENCODING 设置为启动配置 > 通用 > 编码中的编码。并且还将使用该编码执行 sys.setdefaultencoding(它有一个自定义 sitecustomize.py)。

于 2012-06-25T11:47:19.510 回答
0

一种选择是像在 :: 中那样去除字符重音符号,在 python unicode 字符串中删除重音符号的最佳方法是什么?其他位置阅读后,我发现您可以在# -*- coding: utf-8 -*-之后设置选项#!/usr/bin/python以将所有字符串保留在 unicode 中,这可能会有所帮助。在这种情况下,您可能需要运行s = raw_input().decode('utf8')才能获得正确的 unicode。

于 2012-06-17T03:04:46.047 回答