On Mon, May 11, 2015 at 1:53 AM, Somelauw . <somel...@gmail.com> wrote: > In Python 3, decoding "€" with unicode-escape returns 'â\x82¬' which in my > opinion doesn't make sense. > The € already is decoded; if it were encoded it would look like this: > '\u20ac'. > So why is it doing this? > > In Python 2 the behaviour is similar, but slightly different. > > $ python3 -S > Python 3.3.3 (default, Nov 27 2013, 17:12:35) > [GCC 4.8.2] on linux >>>> import codecs >>>> codecs.decode('€', 'unicode-escape') > 'â\x82¬' >>>> codecs.encode('€', 'unicode-escape') > b'\\u20ac' >>>>
Whenever you start encoding and decoding, you need to know whether you're working with bytes->text, text->bytes, or something else. In the case of unicode-escape, it expects to encode text into bytes, as you can see with your second example - you give it a Unicode string, and get back a byte string. When you attempt to *decode* a Unicode string, that doesn't actually make sense, so it first gets *encoded* to bytes, before being decoded. What you're actually seeing there is that the one-character string is being encoded into a three-byte UTF-8 sequence,and then the unicode-escape decode takes those bytes and interprets them as characters; as it happens, that's equivalent to a Latin-1 decode: >>> '€'.encode('utf-8').decode('latin-1') 'â\x82¬' I strongly suggest leaving the codecs module aside, and working exclusively with the str.encode() and bytes.decode() methods, if you possibly can. If you can't, at very least keep track in your head of what is text and what is bytes, and which way things change in every transformation. ChrisA -- https://mail.python.org/mailman/listinfo/python-list