Python2& 3:比较str和unicode

时间:2015-03-24 14:39:14

标签: python string python-3.x unicode python-2.x

我正在努力尝试使用Python2.6,Python 2.7和Python 3.x保持相同的代码运行。

此项目使用python_2_unicode_compatible class decorator以便在str类型中存储非unicode值。

我必须测试函数 foo 返回 str 类型(不是 unicode );返回的值用非ascii字符填充。

我想要的只是测试这个函数返回的值对我自己的字符串,如:

from __future__ import unicode_literals  # so that "àbcéfg" will be read u"àbcéfg"
bool_test = (foo() == "àbcéfg")

我被卡住,因为“àbcéfg”将在Python2中被视为 unicode 字符串,在Python3中被视为 str 字符串。

例如,使用Python2,此代码会引发以下错误:

  

Unicode等同比较无法将两个参数都转换为Unicode - 将它们解释为不等等

有没有一种独特的方法来实现比较,这对Python2和Python3来说很常见?

我尝试了几种解决方案(例如将str转换为字节),但没有成功。

有什么想法可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

您正在比较正确的内容,但foo()没有返回Unicode值。它在Python 2中返回一个字节字符串:

>>> def foo():
...     return u"àbcéfg".encode('utf8')
... 
>>> foo() == u"àbcéfg"
__main__:1: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
False

修复foo()或将其传递给一个函数,该函数解码返回值(如果不是Unicode值)(这里使用six module来桥接Python 2和3中的二进制类型) :

import six

def ensure_unicode(value, encoding='utf8'):
    if isinstance(value, six.binary_type):
        return value.decode(encoding)
    return value

bool_test = ensure_unicode(foo()) == "àbcéfg"

如果foo()意味着在Python 2中返回一个字节串,并在Python 3中返回一个Unicode字符串,那么上面的内容将继续有效,但在Python 2中没有明确验证它是正确的类型;你可以为它添加一个单独的isinstance()测试:

foo_result = foo()
bool_test = isinstance(foo_result, str) and ensure_unicode(foo_result) == "àbcéfg"