String literal Vs Unicode literal Vs unicode type object - 内存表示

时间:2017-06-04 06:26:49

标签: python python-2.7 unicode

Python 2.x doc说,

  

Unicode字符串是一系列代码点

     

Unicode字符串表示为unicode类型

的实例
>>> ThisisNotUnicodeString = 'a정정' # What is the memory representation?
>>> ThisisNotUnicodeString
'a\xec\xa0\x95\xec\xa0\x95\xf0\x9f\x92\x9b'
>>> type(ThisisNotUnicodeString)
<type 'str'>
>>> a = u'a정정' # Which encoding technique used to represent in memory? utf-8?
>>> a
u'a\uc815\uc815\U0001f49b'
>>> type(a)
<type 'unicode'>
>>> b = unicode('a정정', 'utf-8')
>>> b
u'a\uc815\uc815\U0001f49b'
>>> c = unicode('a정정', 'utf-16')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/encodings/utf_16.py", line 16, in decode
    return codecs.utf_16_decode(input, errors, True)
UnicodeDecodeError: 'utf16' codec can't decode byte 0x9b in position 10: truncated data
>>> 

问题:

1)ThisisNotUnicodeString是字符串文字。尽管ThisisNotUnicodeString不是unicode文字,但是哪种编码技术用于在内存中表示ThisisNotUnicodeString?因为应该有一些编码技术来表示内存中的字符。

2)用于在内存中表示unicode文字a的编码技术? UTF-8?如果是,如何知道占用的字节数?

3)为什么c没有使用utf-16技术在内存中表示?

2 个答案:

答案 0 :(得分:2)

  

1)ThisisNotUnicodeString是字符串文字。尽管ThisisNotUnicodeString不是unicode文字,但是哪种编码技术用于在内存中表示ThisisNotUnicodeString?因为应该有一些编码技术来代表정或内存中的字符。

在交互式提示符中,将使用哪种编码来编码Python 2.X的str类型取决于您的shell编码,例如,如果您在Linux系统下运行终端,并且终端的编码为UTF -8:

>>> s = "a정정"
>>> s
'a\xec\xa0\x95\xec\xa0\x95\xf0\x9f\x92\x9b' 

现在尝试将终端窗口中的编码更改为其他内容,在这种情况下,我已将shell的编码从UTF-8更改为WINDOWS-1250:

 >>> s = "a???"

如果您尝试使用tty会话,您会获得钻石而不是?至少在Ubuntu下你可能会得到不同的角色。

您可以断定将使用哪种编码来确定交互式提示中str的编码是否依赖于shell。这适用于在Python解释器下以交互方式运行的代码,不以交互方式运行的代码将引发异常:

#main.py
s = "a정정"

尝试运行代码会引发SynatxError

$ python main.py
SyntaxError: Non-ASCII character '\xec' in file main.py...

这是因为Python 2.X默认使用ASCII:

>>> sys.getdefaultencoding()
'ascii'

然后,您必须通过执行以下操作来指定代码中的编码明确性:

#main.py
#*-*encoding:utf-8*-*
s = "a정정"
  

2)在内存中使用哪种编码技术来表示unicode文字? UTF-8?如果是,如何知道占用的字节数?

请记住,如果您在不同的shell中运行代码,编码方案可能会有所不同,我已在Linux下对此进行了测试,这可能与Windows略有不同,因此请查看操作系统的文档。

要知道占用的字节数,请使用len

>>> s = "a정정"
>>> len(s)
11

s恰好占用11个字节。

  

2)用于在内存中表示unicode文字a的编码技术? UTF-8?如果是,如何知道占用的字节数?

嗯,这是一个混乱,unicode类型没有编码。它只是一系列Unicode字符点(对于Commercial At来说是a.k.a U + 0040)。

  

3)为什么使用utf-16技术在内存中没有表示c

UTF-8是一种与UTF-16不同的编码方案 - UTF-8表示与UTF-16不同的字符字节。在这里:

>>> c = unicode('a정정', 'utf-16')

你基本上是这样做的:

>>> "a정정"
'a\xec\xa0\x95\xec\xa0\x95\xf0\x9f\x92\x9b'
>>> unicode('a\xec\xa0\x95\xec\xa0\x95\xf0\x9f\x92\x9b', 'utf-16')
UnicodeDecodeError: 'utf16' codec can't decode byte 0x9b in position 10: truncated data

这是因为您尝试使用UTF-16 解码 UTF-8。同样,两者都使用不同的字节数来表示字符,它们只是两种不同的编码方案 - 以字节表示字符的不同方式。

供您参考: Python str vs unicode types

答案 1 :(得分:1)

  

用于在内存中表示的编码技术? UTF-8?

您可以尝试以下操作:

ThisisNotUnicodeString.decode('utf-8')

如果你得到一个结果,那就是UTF-8,否则就不行。

如果你想获得字符串的UTF-16表示,你应该先解码它,然后用UTF-16方案编码:

ThisisNotUnicodeString.decode('utf-8').encode('utf-16')

基本上,您可以从/向UTF-8 / UTF-16解码和编码给定字符串,因为所有字符都可以在两种方案中表示。

ThisisNotUnicodeString.decode('utf-8').encode('utf-16').decode('utf-16').encode('utf-8')