Make a quick experiment under version 3.4.4 through this simple "tool" Chris had provided, now I know how the unicode string was stored in memory:-)
>>> s1 = '\x80abc' >>> s1 '\x80abc' >>> len(s1) 4 >>> sys.getsizeof(s1) 41 >>> s1ptr = ctypes.cast(id(s1), ctypes.POINTER(ctypes.c_uint8)) >>> bytes([s1ptr[i] for i in range(41)]) b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x00\x04\xff\x04&\xa4\x00\x00d\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80abc\x00' >>> # a simple unicode string, each code point can be stored in one byte >>> s2 = '\u0080abc' >>> s2 '\x80abc' >>> len(s2) 4 >>> sys.getsizeof(s2) 41 >>> s2ptr = ctypes.cast(id(s2), ctypes.POINTER(ctypes.c_uint8)) >>> bytes([s2ptr[i] for i in range(41)]) b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x00\x04\xff\x04&\xa4\x00\x00|\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80abc\x00' >>> # Python change it automatically to store each code point into one byte >>> s3 = '\u07b4abc' >>> s3 '\u07b4abc' >>> len(s3) 4 >>> sys.getsizeof(s3) 46 >>> s3ptr = ctypes.cast(id(s3), ctypes.POINTER(ctypes.c_uint8)) >>> bytes([s3ptr[i] for i in range(46)]) b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x00\x19n\x93]\xa8\x00\x00dd\r\x1d\x02\x 00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\xb4\x07a\x00b\x00c\x00\x00\x00' >>> # use two bytes to store each code point, even the end-of-string mark >>> s4 = '\U00025049abc' >>> s4 '\U00025049abc' >>> len(s4) 4 >>> sys.getsizeof(s4) 56 >>> s4ptr = ctypes.cast(id(s4), ctypes.POINTER(ctypes.c_uint8)) >>> bytes([s4ptr[i] for i in range(56)]) b'\x01\x00\x00\x00\xe8\xa5g^\x04\x00\x00\x003\xdd\xa7"\xb0\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00IP\x02\x00a\x00\x00\x00b\x 00\x00\x00c\x00\x00\x00\x00\x00\x00\x00' >>> # use four bytes to store each code point --Jach -- https://mail.python.org/mailman/listinfo/python-list