如何以py2和py3两种方式将对象转换为Unicode?

时间:2014-07-17 08:51:37

标签: python python-3.x

我正在尝试修复当我尝试将对象转换为字符串时发生的Python库中的错误。

str(obj)      # fails on py2 when the object return unicode
unicode(obj)  # works perfectly on py2 but fails on py3 

3 个答案:

答案 0 :(得分:0)

由于unicode在从Python 2迁移到Python 3时变为标准str类型(str变成bytes),因此解决此问题的一种方法在Python 2和3中运行的方式问题是在Python 3中运行时将unicode定义为等同于str。这通常在需要支持这两个Python版本的库中完成,示例可以在oauthlib.commonrequests.compat(包括更全面的兼容性层)中找到。对于该库的内部任何调用,只要需要确保在检查不变量/断言,强制转换等时需要bytesstr,就会引用该类型。

答案 1 :(得分:0)

Django为此提供了一个简洁的解决方案,他们为用户提供了一个可以应用于该类的装饰器。

def python_2_unicode_compatible(klass):
    """
    A decorator that defines __unicode__ and __str__ methods under Python 2.
    Under Python 3 it does nothing.

    To support Python 2 and 3 with a single code base, define a __str__ method
    returning text and apply this decorator to the class.
    """
    if six.PY2:
        if '__str__' not in klass.__dict__:
            raise ValueError("@python_2_unicode_compatible cannot be applied "
                             "to %s because it doesn't define __str__()." %
                             klass.__name__)
        klass.__unicode__ = klass.__str__
        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
    return klass

这取决于python库六。 (请注意代码许可!)

答案 2 :(得分:0)

你可以使用%s格式来获取2.7中的unicode()和3.5中的str(),只要你导入每个人都应该做的unicode_literals

我发现这个技巧非常有用,并且不需要在任何地方导入compat库。

PY 2.7x

>>> from __future__ import unicode_literals
>>> "%s" % 32
u'32'  (<type 'unicode'>)

PY 3.5

>>> ("%s" % (42)).__class__
<class 'str'>

在此处添加此项,因为这是我在寻找除six.text_type(value)或其他compat库以外的其他内容时谷歌中出现的第一个结果。