Yanıtlar:
Python 3 varsayarsak (Python 2'de bu fark biraz daha az iyi tanımlanmıştır) - dize bir karakter dizisidir, yani unicode kod noktaları ; bunlar soyut bir kavramdır ve doğrudan diskte depolanamaz. Bir bayt dizisi, dizisidir, beklendiği üzere bayt - şeyleri yapabilirsiniz diskte depolanabilir. Aralarındaki eşleme bir kodlamadır - bunlardan çok fazla vardır (ve sonsuz sayıda mümkündür) - ve dönüşümü yapmak için belirli bir durumda hangisinin geçerli olduğunu bilmeniz gerekir, çünkü farklı bir kodlama aynı baytları eşleyebilir farklı bir dizeye:
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16')
'蓏콯캁澽苏'
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8')
'τoρνoς'
Hangisini kullanacağınızı öğrendikten sonra .decode()
, yukarıdaki gibi doğru karakter dizesini almak için bayt dizesinin yöntemini kullanabilirsiniz . Tamlık için .encode()
, bir karakter dizesinin yöntemi tam tersine gider:
>>> 'τoρνoς'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'
str
nesnelerinin bellek içi gösterimine Python tarafından erişilemez veya ilgili değildir; veri yapısı sadece bir kod noktası dizisidir. PEP 393 altında , tam dahili kodlama Latin-1, UCS2 veya UCS4'ten biridir ve bir utf-8 gösterimi ilk istendikten sonra önbelleğe alınabilir, ancak C kodu bile bu dahili detaylara güvenmekten vazgeçirilebilir.
Bir bilgisayarın depolayabileceği tek şey bayttır.
Bilgisayarda herhangi bir şey saklamak için önce onu kodlamanız , yani bayta dönüştürmeniz gerekir. Örneğin:
MP3
, WAV
vbPNG
, JPEG
vbASCII
, UTF-8
vbMP3
, WAV
, PNG
, JPEG
, ASCII
Ve UTF-8
örnek olarak kodlama . Kodlama, sesi, görüntüleri, metni vb. Bayt cinsinden temsil eden bir formattır.
Python'da bir bayt dizesi sadece şudur: bir bayt dizisi. İnsan tarafından okunabilir değil. Kaputun altında, her şey bir bilgisayarda saklanmadan önce bir bayt dizesine dönüştürülmelidir.
Öte yandan, genellikle "dize" olarak adlandırılan bir karakter dizesi bir karakter dizisidir. İnsan tarafından okunabilir. Bir karakter dizisi doğrudan bir bilgisayarda saklanamaz, önce kodlanması gerekir (bayt dizesine dönüştürülür). Bir karakter dizesinin ASCII
ve gibi bir bayt dizesine dönüştürülebileceği birden çok kodlama vardır UTF-8
.
'I am a string'.encode('ASCII')
Yukarıdaki Python kodu, kodlamayı 'I am a string'
kullanarak dizeyi kodlayacaktır ASCII
. Yukarıdaki kodun sonucu bir bayt dizesi olacaktır. Yazdırırsanız, Python bunu temsil edecektir b'I am a string'
. Bununla birlikte, bayt dizelerinin insan tarafından okunamayacağını , sadece Python'un bunları ASCII
yazdırdığınızda çözdüğünü unutmayın. Python'da, bir bayt dizesi a ile b
, ardından bayt dizesinin ASCII
temsiliyle temsil edilir.
Bir bayt dizesi, onu kodlamak için kullanılan kodlamayı biliyorsanız, bir karakter dizesine geri deşifre edilebilir .
b'I am a string'.decode('ASCII')
Yukarıdaki kod orijinal dizeyi döndürür 'I am a string'
.
Kodlama ve kod çözme ters işlemdir. Her şey diske yazılmadan önce kodlanmalı ve bir insan tarafından okunmadan önce deşifre edilmesi gerekir.
Not: Python 2'nin ömrünün sonuna çok yakın olduğu için Python 3 için cevabımı daha ayrıntılı olarak açıklayacağım.
Python 3'te
bytes
8 bit işaretsiz değerlerin str
dizilerinden oluşurken, insan dillerindeki metin karakterlerini temsil eden Unicode kod noktalarının dizilerinden oluşur.
>>> # bytes
>>> b = b'h\x65llo'
>>> type(b)
<class 'bytes'>
>>> list(b)
[104, 101, 108, 108, 111]
>>> print(b)
b'hello'
>>>
>>> # str
>>> s = 'nai\u0308ve'
>>> type(s)
<class 'str'>
>>> list(s)
['n', 'a', 'i', '̈', 'v', 'e']
>>> print(s)
naïve
Olsa bytes
ve str
aynı şekilde çalışır gibi görünüyor, onların örneklerini yani birbirleri ile uyumlu değildir, bytes
ve str
örnekleri gibi operatörleri ile birlikte kullanılamaz >
ve +
. Ayrıca, karşılaştırma bytes
ve str
eşitlik için örneklerin, yani kullanımın ==
, False
tam olarak aynı karakterleri içerdiklerinde bile her zaman değerlendireceğini unutmayın .
>>> # concatenation
>>> b'hi' + b'bye' # this is possible
b'hibye'
>>> 'hi' + 'bye' # this is also possible
'hibye'
>>> b'hi' + 'bye' # this will fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>> 'hi' + b'bye' # this will also fail
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>>
>>> # comparison
>>> b'red' > b'blue' # this is possible
True
>>> 'red'> 'blue' # this is also possible
True
>>> b'red' > 'blue' # you can't compare bytes with str
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'bytes' and 'str'
>>> 'red' > b'blue' # you can't compare str with bytes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'bytes'
>>> b'blue' == 'red' # equality between str and bytes always evaluates to False
False
>>> b'blue' == 'blue' # equality between str and bytes always evaluates to False
False
Yerleşik işlev kullanılarak döndürülen dosyalarla çalışırken bytes
ve çalışırken başka bir sorun var . Bir yandan, bir dosyaya ikili veri okumak veya yazmak istiyorsanız, dosyayı her zaman 'rb' veya 'wb' gibi bir ikili mod kullanarak açın. Öte yandan, bir dosyaya / dosyasından Unicode veri okumak veya yazmak istiyorsanız, bilgisayarınızın varsayılan kodlamasının farkında olun, bu yüzden gerekirse sürprizlerden kaçınmak için parametreyi geçin.str
open
encoding
Python 2'de
str
8 bitlik değer unicode
dizilerinden oluşur, Unicode karakter dizilerinden oluşur. Akılda tutulması gereken bir şey, str
ve sadece 7 bit ASCI karakterlerinden oluşuyorsa unicode
işleçlerle birlikte kullanılabileceğidir str
.
Arasına dönüştürmek için yardımcı işlevlerini kullanmak yararlı olabilir str
ve unicode
Python 2'de ve aralarında bytes
ve str
Python 3'te.
Gönderen Unicode nedir :
Temel olarak, bilgisayarlar sadece sayılarla ilgilenir. Her biri için bir sayı atayarak harfleri ve diğer karakterleri saklarlar.
......
Unicode, platform ne olursa olsun, program ne olursa olsun, dil ne olursa olsun her karakter için benzersiz bir sayı sağlar.
Bir bilgisayar bir dizeyi temsil ettiğinde, dizenin bilgisayarında depolanan karakterleri benzersiz Unicode numaraları aracılığıyla bulur ve bu rakamlar bellekte depolanır. Ancak dizeyi doğrudan diske yazamaz veya dizeyi benzersiz Unicode numaraları aracılığıyla ağ üzerinde iletemezsiniz, çünkü bu rakamlar sadece basit ondalık sayıdır. Dizeyi, bayt dizesi gibi kodlamanız gerekir UTF-8
. UTF-8
tüm olası karakterleri kodlama yeteneğine sahip kodlayan bir karakterdir ve bayt (benziyor gibi karakterleri saklayan bu ). Böylece kodlanmış dize her yerde kullanılabilir çünkü UTF-8
neredeyse her yerde desteklenir. Kodlanmış bir metin dosyasını açtığınızdaUTF-8
diğer sistemlerden, bilgisayarınız onu çözer ve benzersiz Unicode numaraları aracılığıyla içindeki karakterleri görüntüler. Bir tarayıcı UTF-8
ağdan kodlanmış dize verisi aldığında , verinin kodunu çözer ( UTF-8
kodlamanın tarayıcıda olduğunu varsayar ) ve dizeyi görüntüler.
Python3 içinde, dizeyi ve bayt dizesini birbirine dönüştürebilirsiniz:
>>> print('中文'.encode('utf-8'))
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
中文
Tek kelimeyle, dize bir bilgisayarda okumak için insanlara göstermek için ve bayt dize disk ve veri iletiminde saklamak içindir.
Unicode, karakterlerin ve çeşitli biçimlendirme türlerinin (örn. Küçük harf / büyük harf, yeni satır, satır başı) ve diğer "şeylerin (örn. Emojiler) ikili gösterimi için üzerinde anlaşmaya varılmış bir biçimdir. Bilgisayar, ister bellekte ister dosyada olsun, bir unicode temsilini (bir dizi bit) depolamak için bir ascii temsilini (farklı bir bit dizisi) veya başka bir temsili (bit dizisi) depolamaktan daha az yetenekli değildir. ).
İçin iletişim gerçekleşmesi, iletişim taraf kullanılacaktır neler temsil katılıyorum gerekir.
Unicode, insanlar arası ve bilgisayarlararası iletişimde kullanılan tüm olası karakterleri (ve diğer "şeyleri") temsil etmeye çalıştığından, diğer temsil sistemlerinden daha fazla karakterin (veya nesnenin) gösterilmesi için daha fazla sayıda bit gerektirir. daha sınırlı sayıda karakter / şeyi temsil etmeye çalışın. "Basitleştirmek" ve belki de tarihsel kullanıma uyum sağlamak için, unicode gösterimi karakterleri dosyalarda saklamak amacıyla neredeyse tamamen başka bir temsil sistemine (örneğin ascii) dönüştürülür.
Bu unicode Eğer durum değildir olamaz dosyalarında karakterleri depolamak ya yoluyla iletmek için kullanılacak herhangi basitçe o, iletişim kanalı olduğunu değil.
"String" terimi tam olarak tanımlanmamıştır. "String", ortak kullanımında bir dizi karakter / şeyi ifade eder. Bir bilgisayarda, bu karakterler birçok farklı uçtan uca gösterimden birinde depolanabilir. "Bayt dizesi", sekiz bit (sekiz bit bayt olarak adlandırılır) kullanan bir gösterim kullanılarak depolanan bir karakter kümesidir. Bu günlerde bilgisayarlar karakterleri bellekte saklamak için unicode sistemini (değişken sayıda baytla temsil edilen karakterler) ve karakterleri dosyalara depolamak için bayt dizelerini (tek baytla temsil edilen karakterler) kullandığından, temsil edilen karakterlerden önce bir dönüşüm kullanılmalıdır bellekte dosyalarda depoya taşınacaktır.
Basit bir tek karakterli dize alalım 'š'
ve bunu bir bayt dizisine kodlayalım:
>>> 'š'.encode('utf-8')
b'\xc5\xa1'
Bu örneğin amacı için bayt dizisini ikili biçimde gösterelim:
>>> bin(int(b'\xc5\xa1'.hex(), 16))
'0b1100010110100001'
Şimdi, nasıl kodlandığını bilmeden bilgilerin şifresini çözmek genellikle mümkün değildir . Yalnızca utf-8
metin kodlamasının kullanıldığını biliyorsanız, utf-8 kodunu çözmek için algoritmayı takip edebilir ve orijinal dizeyi edinebilirsiniz:
11000101 10100001
^^^^^ ^^^^^^
00101 100001
İkili sayıyı 101100001
bir dize olarak geri görüntüleyebilirsiniz :
>>> chr(int('101100001', 2))
'š'
Python dilleri içerir str
ve bytes
standart olarak "Yerleşik türleri". Başka bir deyişle, her ikisi de sınıftır. Python'un neden bu şekilde uygulandığını rasyonelleştirmeye çalışmak gerektiğini düşünmüyorum.
Bunu söyledikten str
ve bytes
birbirine çok benzer. Her ikisi de aynı yöntemlerin çoğunu paylaşır. Aşağıdaki yöntemler str
sınıfa özgüdür :
casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable
Aşağıdaki yöntemler bytes
sınıfa özgüdür :
decode
fromhex
hex
str
tür, türle aynıdırbytes
; bu cevap,unicode
türü (Python 3'te yoktur) tür ile eşdeğer olarak karşılaştırırstr
.