Mieszane są typy obiektów .
'£'
to bytestring, zawierający zakodowane dane. To, że te bajty przedstawiają znak funta w twoim terminalu lub konsoli, ani tu, ani tam, może być tak samo jak piksel na obrazie. Twój terminal lub konsola jest skonfigurowana tak, aby produkować i akceptować dane UTF-8, więc zawartość tego testu to dwa bajtów C2 i A3, po wyrażeniu w postaci szesnastkowej.
u'1'
z drugiej strony jest ciągiem Unicode. Jest to jednoznaczne dane tekstowe. Jeśli chcesz dołączyć do niego inne dane, to również powinien to być kod Unicode. Python 2 następnie automatycznie zdekoduje str
bajtów do Unicode za pomocą domyślnego kodeka ASCII, jeśli spróbujesz to zrobić.
Mimo to, testowanie '£'
nie podlega dekodowaniu jako ASCII. To może być dekodowane jako UTF-8; zdekodować bajty jednoznacznie, ponieważ wiemy prawidłowego kodeka tutaj:
print '£'.decode('utf8') + u'1'
Pisząc bajtów do terminala lub konsoli, to terminal lub konsola który interpretuje bajty i sensowne z nich. Jeśli napiszesz obiekt unicode
do terminala, obiekt sys.stdout
zajmie się kodowaniem, konwertując tekst na bajty, które zrozumie twój terminal lub konsola.
To samo dotyczy przyjmowania danych wejściowych; strumień sys.stdin
generuje bajty, które Python może dekodować przezroczysto podczas używania składni u'£'
do utworzenia obiektu Unicode. Wpisujesz znak na klawiaturze, jest on tłumaczony na bajty UTF-8 przez terminal lub konsolę i zapisywany w Pythonie w celu zinterpretowania.
Pisanie '\xc2\xa3'
z print
działa, więc jest szczęśliwym zbiegiem okoliczności. Można wziąć przedmiot unicode
, zakodować do różnych kodeka, a kończy się z wyjściem na śmieci:
>>> print u'£1'.encode('latin-1')
?1
zacisk My Mac przekształcone dane zapisane na znak £
do ?
, ponieważ bajt A3 (numer kodowy Latin-1 dla znaku funta) nie mapuje się do niczego po interpretacji jako UTF-8.
Python określa kodek terminala lub konsoli z locale.getpreferredencoding()
function, można obserwować co terminal lub konsola przekazane używa poprzez sys.stdout.encoding
i sys.stdin.encoding
atrybutów:
>>> import sys
>>> sys.stdout.encoding
'UTF-8'
Last but not least, nie należy mylić drukowanie z reprezentacjami wyświetlanymi przez interpreter w trybie interaktywnym. Interpreter pokazuje wynik wyrażeń za pomocą funkcji repr()
, narzędzia do debugowania, które próbuje utworzyć literacką notację w języku Python wszędzie tam, gdzie jest to możliwe, używając znaków ASCII w postaci tylko. W przypadku wartości Unicode oznacza to, że dowolny niedrukowalny, nie-ASCII znak jest odbijany przy użyciu sekwencji ucieczki. To sprawia, że wartość nadaje się do kopiowania i wklejania bez konieczności używania więcej niż medium obsługującego ASCII.
repr()
wynikiem str
wykorzystuje \n
do nowej linii, na przykład, sześciokątny \xhh
uchodzi do bajtów bez określonych sekwencje, do strefy drukowania. Ponadto, dla unicode
obiektów codepoints poza zakresu Latin-1 są reprezentowane z \uhhhh
i \Uhhhhhhhh
sekwencje w zależności od wether czy nie są one częścią podstawowego samolotu wielojęzycznym:
>>> u'''\
... A multiline string to show newlines
... can contain £ latin characters
... or emoji !
... '''
u'A multiline string to show newlines\ncan contain \xa3 latin characters\nor emoji \U0001f4a9!\n'
>>> print _
A multiline string to show newlines
can contain £ latin characters
or emoji !
AFAIK można tylko concat struny ten sam typ, tj. 'u '£' + u'1'' lub' '£' + '1''. Nie możesz ich mieszać. – Bjorn
Próbujesz rozszyfrować jako ascii za pomocą 'print '£' + u'1'', nigdy nie zobaczysz' '\ xc2 \ xa31'' kiedy drukujesz, chyba że wydrukujesz' repr' obiektu, ' print '£' + '1'' działa, ponieważ twoja powłoka jest skonfigurowana do akceptowania utf-8 –
@Bjorn Możesz, zrobiłem to wiele razy, zobacz zaktualizowane pytanie – texasflood