2013-03-13 14 views
6

W Pythonie 3, w jaki sposób interpolować ciąg bajtów w zwykły ciąg i uzyskać takie samo zachowanie, jak w Pythonie 2 (tj. Uzyskać tylko kody escape bez prefiksu b lub podwójnych ukośników)?Python 3: Jak uzyskać ciąg literału reprezentujący ciąg bajtów?

np .:

Python 2.7:

>>> x = u'\u041c\u0438\u0440'.encode('utf-8') 
>>> str(x) 
'\xd0\x9c\xd0\xb8\xd1\x80' 
>>> 'x = %s' % x 
'x = \xd0\x9c\xd0\xb8\xd1\x80' 

Python 3.3:

>>> x = u'\u041c\u0438\u0440'.encode('utf-8') 
>>> str(x) 
"b'\\xd0\\x9c\\xd0\\xb8\\xd1\\x80'" 
>>> 'x = %s' % x 
"x = b'\\xd0\\x9c\\xd0\\xb8\\xd1\\x80'" 

Uwaga jak w Pythonie 3, pojawia się przedrostek b w moim wyjściu i podwójne podkreślenia. Wynik że chciałbym dostać wynika, że ​​mam w Pythonie 2.

+0

W przykładzie Python 3, jesteś interpolację na ciąg znaków Unicode, a nie ciąg bajtów jak robisz w Pythonie 2. –

Odpowiedz

4

W Pythonie 2 Zostały rodzajów str i unicode. str reprezentuje prosty ciąg bajtowy, a unicode jest ciągiem znaków Unicode.

dla Pythona 3, to się zmieniło: Teraz str co było unicode w Pythonie 2 i byte co było str w Pythonie 2.

Więc kiedy zrobić ("x = %s" % '\u041c\u0438\u0440').encode("utf-8") rzeczywiście można pominąć prefiks u, jak to jest domniemany. Wszystko, co nie jest jawnie konwertowane w pythonie, to unikod.

To przyniesie swój ostatni wiersz w Pythonie 3:

("x = %s" % '\u041c\u0438\u0440').encode("utf-8") 

Teraz jak zakodować po wynik końcowy, czyli to, co zawsze należy zrobić: Weź obiektu przychodzącego, dekoduje go na Unicode (jakkolwiek to robisz), a następnie, podczas tworzenia wyjścia, zakoduj go w wybranym kodowaniu. Nie próbuj obsługiwać surowych ciągów bajtów. To po prostu brzydkie i przestarzałe zachowanie.

+0

Tak, kodowanie po wyniku wydaje się lepszym sposobem. Dzięki! –

3

W przykładzie Python 3, jesteś interpolację na ciąg znaków Unicode, a nie ciąg bajtów jak robisz w Pythonie 2.

W języku Python 3, bytes nie obsługuje interpolacji (formatowanie ciągów znaków lub co-ty-użytkownik).

Albo łączyć lub używać Unicode wszystko tylko zakodować gdy masz interpolowane i przez:

b'x = ' + x 

lub

'x = {}'.format(x.decode('utf8')).encode('utf8') 

lub

x = '\u041c\u0438\u0440' # the u prefix is ignored in Python 3.3 
'x = {}'.format(x).encode('utf8') 
+0

Tak, kodowanie po wyniku wydaje się lepszym rozwiązaniem. Dzięki! –

0

W języku Python 2 ciągi znaków i ciągi znaków są takie same, więc nie ma konwersji wykonanej przez str(). W Pythonie 3 ciąg jest zawsze ciągiem Unicode, więc str() ciągu znaków bajtowych dokonuje konwersji.

można zrobić własną przemianę, a nie, że robi to, co chcesz:

x2 = ''.join(chr(c) for c in x) 
Powiązane problemy