Hier kann man übrigens nochmal genauer sehen, dass im Grunde alles nur Interpretationssache ist:
Es geht beide Male um den Dezimalwert 77. Bei der ersten Variante, wird er in hexadezimaler Form angegeben, sodass seine *Entsprechung* (dezimal) als Integer ausgegeben wird. In der zweiten Variante wird die besondere Stringform (`\x`) angegeben, sodass für den daran anschließenden hexadezimalen Wert (`4d`) das passende Zeichen rausgesucht werden kann.
Man kann das auch noch weiter fassen:
Code: Alles auswählen
>>> '\x80'
'\x80'
>>> '\x80'.decode('windows-1252')
u'\u20ac'
>>> print '\x80'.decode('windows-1252')
€
Der Hex-Wert 80 (nicht mit Dezimal verwechseln) hat im ASCII-Zeichensatz keine Entsprechung. Daher wird er ohne "Ersetzung", quasi in "Reinform" angezeigt. Bei der Verwendung eines Unicode-Zeichensatzes benutzt Python 2.x (Python3 funktioniert anders) stattdessen eine entsprechende Unicode-Zeichenkette (`u'\u20ac'`). Beachte, dass diese Darstellung immer noch genau einem Zeichen entspricht - "speichertechnisch" jedoch nicht mehr einem Byte, sondern jetzt 2 Bytes.¹ Schickt man diese schließlich an den Ausgabestrom des Terminals (mittels `print`), dann erkennt man, dass dieses "kryptische Ding" durch den Zeichensatz als Euro-Zeichen interpretiert wird.
Aber das nur nebenbei. Möglicherweise verstehst du Thematik damit ein bißchen besser...
̣̣_____
¹ Um korrekt zu bleiben: Bereits das Speichern des Hex-Wertes 80 verbraucht 2 Bytes, weil es von der Größe her halt nicht mehr in ein Byte reinpasst. Nicht, dass es sich so anhört, als käme der Zusatzverbrauch durch das Encoding...