Encode / decode arasındaki fark nedir?


180

Asla str / unicode decode ve encode arasındaki farkı anladığımdan emin olamadım.

Bunu biliyorum str().decode()adını kodlayan bir unicode dize döneceğini verilen belli bir karakter kodlaması vardır biliyorum sen bayt bir dize olduğunda içindir.

unicode().encode()Unicode karakterleri verilen bir kodlama adına göre bayt dizesine dönüştürür biliyorum .

Ama ne için olduğunu str().encode()ve ne unicode().decode()için olduğunu anlamıyorum . Yukarıda yanlış yaptığım herhangi bir şeyi açıklayabilir ve muhtemelen düzeltebilir miyim?

DÜZENLE:

Birkaç cevap .encodebir dizgide ne yaptığına dair bilgi verir , ancak hiç kimse .decodeunicode için ne yaptığını bilmiyor gibi görünüyor .


Bu sayfanın ikinci cevabının yeterince açık ve özlü olduğunu düşünüyorum.
Ben

Yanıtlar:


106

decode(- aşağıya bakın bir nedenle bir unicode dize bazı metin dışı veri yoksa) Unicode dizeleri yöntem gerçekten hiç herhangi bir uygulama bulunmamaktadır. Sanırım, çoğunlukla tarihsel nedenlerden ötürü orada. Python 3'te tamamen gitti.

unicode().decode()örtülü bir gerçekleştirecek kodlama bölgesinin svarsayılan (ASCII) codec kullanarak. Bunu şöyle doğrulayın:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

>>> s.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

Hata mesajları tamamen aynıdır.

İçin str().encode()tam tersi - bu örtük bir girişimleri çözme ait svarsayılan kodlama:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)

Bu şekilde kullanıldığında, str().encode()gereksizdir.

Ancak , ikinci yöntemin yararlı olan başka bir uygulaması vardır: karakter kümeleriyle ilgisi olmayan kodlamalar vardır ve bu nedenle 8 bit dizelere anlamlı bir şekilde uygulanabilir:

>>> s.encode('zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

Yine de haklısın: Her iki uygulama için de "kodlamanın" belirsiz kullanımı ... awkard. Yine, Python 3'teki ayrı byteve stringtürlerle, bu artık bir sorun değildir.


4
.decode()Unicode dizelerinde yararlı olabilir örneğin,print u'\\u0203'.decode('unicode-escape')
jfs

Python3 iyi örnek @JFSebastian Yaparım:print u'\\u0203'.encode('utf8').decode('unicode-escape')
AJP

1
@AJP: Python 3'te:codecs.decode(u'\\u0203', 'unicode-escape')
jfs

@hop: evet. Geçersiz girişi algılamak ve Python 2/3 uyumluluğu için, dize asciikodlama kullanılarak açıkça kodlanabilir:\\u0203\u00e4'.encode('ascii').decode('unicode-escape')
jfs

@hop: ilk yorumunuz (Neden sildiniz? Yanıtlanan yorumları silmeyin) zaten söyledi. Cevabım ( .encode('ascii').decode('unicode-escape')) bağlı değil sys.getdefaultencoding().
jfs

71

Bir unicode dizgiyi bayt dizesi olarak temsil etmek kodlama olarak bilinir . Kullanın u'...'.encode(encoding).

Misal:

    >>> u'æøå'.encode ('utf8')
    '\ XC3 \ X83 \ XC2 \ XA6 \ XC3 \ X83 \ XC2 \ xb8 \ XC3 \ X83 \ XC2 \ xa5'
    >>> u'æøå'.encode ('latin1')
    '\ XC3 \ XA6 \ XC3 \ xb8 \ XC3 \ xa5'
    >>> u'æøå'.encode ('ascii')
    UnicodeEncodeError: 'ascii' codec bileşeni 0-5 arasındaki karakterleri kodlayamaz: 
    sıra dışı menzil (128)

Genellikle bir unicode dizesini IO için kullanmanız gerektiğinde kodlarsınız, örneğin ağ üzerinden aktarın veya bir disk dosyasına kaydedin.

Bir bayt dizesini bir unicode dizeye dönüştürmek kod çözme olarak bilinir . Kullanım unicode('...', encoding)veya '...'. Kod çözme (kodlama).

Misal:

   >>> u'æøå '
   u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5' # yorumlayıcı unicode nesnesini böyle yazdırır
   >>> unicode ('\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5', 'latin1')
   u '\ XC3 \ XA6 \ XC3 \ xb8 \ XC3 \ xa5'
   >>> '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'.decode (' latin1 ')
   u '\ XC3 \ XA6 \ XC3 \ xb8 \ XC3 \ xa5'

Ağdan veya bir disk dosyasından dize verisi aldığınızda, genellikle bir bayt dizisinin kodunu çözersiniz.

Python 3'te unicode kullanımında bazı değişiklikler olduğuna inanıyorum, bu yüzden yukarıdaki muhtemelen python 3 için doğru değil.

Bazı iyi bağlantılar:


6
OP'nin sorusuna cevap vermedin. OP, str.encode () ve unicode.decode () öğelerinin ne yaptığını bilmek istiyor. Orijinal soruda belirtilenleri tekrarladınız.
stuckintheshuck

Uygulamada neden kod çözme ve kodlama ile uğraştığınıza harika bir cevap. Her makine aynı karakter kümesini anlamaz, ancak hepsi baytları anlar. Bilgisayarların evrensel olarak anladığı (ve diske aktarılabildiği veya diske kaydedilebildiği) için baytlara kodlayın, ancak insanlar gerçekten bu baytları okumak zorunda kaldığında kod çözme (örn. İstemci tarafında).
Alex Petralia

Harika bir cevap! Bu yukarı gitmeli !!
sandyp

16

anUnicode. encode ('encoding') bir dize nesnesiyle sonuçlanır ve bir unicode nesnesinde çağrılabilir

dizi. kod çözme ('kodlama') bir unicode nesnesiyle sonuçlanır ve verilen kodlamada kodlanmış bir dizede çağrılabilir.


Bazı açıklamalar:

Kodlama seti olmayan bazı unicode nesneleri oluşturabilirsiniz. Python tarafından hafızada saklanma şekli endişe etmiyor. Onu arayabilir, bölebilir ve istediğiniz herhangi bir dize düzenleme işlevini çağırabilirsiniz.

Ancak, unicode nesnenizi konsola veya bazı metin dosyalarına yazdırmak istediğiniz bir zaman gelir. Bu yüzden kodlamanız gerekir (örneğin - UTF-8'de), encode ('utf-8') öğesini çağırırsınız ve içeride '\ u <someNumber>' ile mükemmel bir şekilde yazdırılabilir bir dize alırsınız.

Sonra tekrar - UTF-8 olarak kodlanmış okuma dize ve bir Unicode olarak davranın, \ u360 5. Sonra değil, bir karakter olacağını böylece - tam tersini yapmak istiyorum deşifre (seçilen kodlama) bir dize ve unicode türünde yepyeni bir nesne edinin.

Yan not olarak - 'zip', 'base64', 'rot' gibi bazı sapık kodlamaları seçebilirsiniz ve bazıları dizeden dizeye dönüşür, ancak en yaygın durumun UTF-8 içeren bir kod olduğuna inanıyorum / UTF-16 ve dize.


12

mybytestring.encode (somecodec) şu değerler için anlamlıdır somecodec:

  • base64
  • bz2
  • zlib
  • büyü
  • quopri
  • ROT13
  • string_escape
  • uu

Zaten çözülmüş bir unicode metnin kodunun ne için çözüldüğünden emin değilim. Bunu herhangi bir kodlama ile denemek her zaman önce sistemin varsayılan kodlaması ile kodlamaya çalışmaktadır.


5

Str'den str'ye veya unicode'dan unicode'a kod çözme / kodlama için kullanılabilecek birkaç kodlama vardır. Örneğin base64, hex veya hatta rot13. Bunlar codec bileşenleri modülünde listelenir .

Düzenle:

Unicode dizgideki kod çözme iletisi, karşılık gelen kodlama işlemini geri alabilir:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

Döndürülen türü bence talihsiz unicode yerine str olduğunu. Ancak str ve unicode arasında düzgün bir en- / decode yapmıyorsanız, bu yine de bir karışıklık gibi görünüyor.


1
-1: Kod çözme yöntemi unicode nesnesine uygulanmıyor. Bunun yerine, unicode nesnesi, kod çözme işlemi başlamadan önce bir 'ascii' bytestring olarak kodlanır. Bu iddianın kanıtı için, UnicodeEncodeError
nosklo

2
@nosklo: Haklısın. Gerçekten demek istediğim, unicode nesnelerin de onlara kod olmayan kodlama kodekleri uygulayabileceğiniz bir decode () yöntemine sahip olması. Bu karakter olmayan tüm kodlama işi, bu arayüzü Python <3'te bir karmaşa haline getiriyor.

1

Basit cevap, birbirlerinin tam tersidir.

Bilgisayar bilgileri saklamak ve işlemek için çok temel bayt birimini kullanır; insan gözü için anlamsızdır.

Örneğin, '\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87' iki Çince karakterin temsilidir, ancak bilgisayar bunu aramak için bir sözlük verildiğinde yalnızca Çince Karakterler olduğunu bilir (yazdırma veya saklama anlamına gelir) Çince kelime, bu durumda, bir "utf-8" sözlüğüdür ve farklı veya yanlış bir sözlüğe (farklı bir kod çözme yöntemi kullanarak) bakarsanız, amaçlanan Çince kelimeyi doğru bir şekilde gösteremez.

Yukarıdaki durumda, bir bilgisayarın Çince kelime araması işlemi decode().

Ve bilgisayar Çinliler bilgisayar hafızasına yazma süreci encode().

Bu nedenle, kodlanmış bilgi ham bayttır ve kodu çözülen bilgi, başvurulan sözlüğün ham baytları ve adıdır (ancak sözlüğün kendisi değildir).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.