转换为unicode的正确方法是什么?

时间:2013-11-13 11:23:40

标签: python unicode

假设你有一个字符串

s = "C:\Users\Eric\Desktop\beeline.txt"

如果不是,你想转移到Unicode。

return s if PY3 or type(s) is unicode else unicode(s, "unicode_escape")

如果字符串有可能具有\ U(即用户目录),并且您可能会遇到Unicode解码错误。

UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 3-4: truncated \UXXXXXXXX escape

像这样强迫它是否有任何不妥之处:

return s if PY3 or type(s) is unicode else unicode(s.encode('string-escape'), "unicode_escape")

或明确检查是否存在\ u ok,因为它是唯一的一个角落?

我希望代码适用于python 2& 3。

3 个答案:

答案 0 :(得分:0)

它适用于英语,但是当遇到实际的unicode示例时,强制转换可能不会使用与默认情况下相同的编码,从而使您产生不愉快的错误。

我将你给定的代码包装在一个名为assert_unicode的函数中(用isinstance替换了is)并对希伯来语中的文本进行了测试(简单地说'你好'),检查出来:

In [1]: def assert_unicode(s):
            return s if isinstance(s, unicode) else unicode(s, 'unicode_escape')    

In [2]: assert_unicode(u'שלום')
Out[2]: u'\u05e9\u05dc\u05d5\u05dd'

In [3]: assert_unicode('שלום')
Out[3]: u'\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d'
你知道吗?两者都返回一个unicode对象,但仍然存在很大差异。如果您尝试打印或使用第二个示例,它可能会失败(例如,一个简单的打印对我来说失败了,我正在使用非常友好的unicode的console2。)

解决这个问题? 使用utf-8 。这些天来它是一个标准,如果你确保一切都将被视为utf-8,它应该像任何特定语言的魅力一样工作:

In [4]: def assert_unicode(s):
            return s if isinstance(s, unicode) else unicode(s, 'utf-8')    

In [5]: assert_unicode(u'שלום')
Out[5]: u'\u05e9\u05dc\u05d5\u05dd'

In [6]: assert_unicode('שלום')
Out[6]: u'\u05e9\u05dc\u05d5\u05dd'

答案 1 :(得分:0)

以下例程在精神上类似于@yuvi的答案,但它经历了多个编码(可配置)并返回使用的编码。它还可以更优雅地处理错误(仅通过转换basetring的内容)。

#unicode practice, this routine forces stringish objects to unicode
#preferring utf-8 but works through other encodings on error
#return values are the encoded string and the encoding used
def to_unicode_or_bust_multile_encodings(obj, encoding=['utf-8','latin-1','Windows-1252']):
  'noencoding'
  successfullyEncoded = False
  for elem in encoding:
    if isinstance(obj, basestring):
      if not isinstance(obj, unicode):
        try:
          obj = unicode(obj, elem)
          successfullyEncoded = True
          #if we succeed then exit early
          break
        except:
          #encoding did not work, try the next one
          pass

  if successfullyEncoded:
    return obj, elem
  else:
    return obj,'no_encoding_found'

答案 2 :(得分:0)

  

转换为unicode的正确方法是什么?

这是:

unicode_string = bytes_object.decode(character_encoding)

现在问题变成了:我有一个字节序列,我应该使用什么字符编码将它们转换为Unicode字符串?

答案取决于字节的来源。

在您的情况下,bytestring是使用Python字符串为字节串(Python 2)指定的,因此编码是Python源文件的字符编码。如果文件顶部没有字符编码声明(注释类似于:# -*- coding: utf-8 -*-),则Python 2上的默认源编码为'ascii''utf-8' - Python 3 )。所以你的答案是:

if isinstance(s, str) and not PY3:
   return s.decode('ascii')

或者你可以直接使用Unicode文字(Python 2和Python 3.3 +):

unicode_string = u"C:\\Users\\Eric\\Desktop\\beeline.txt"