인코딩 / 디코딩의 차이점은 무엇입니까?


180

str / unicode 디코딩과 인코딩의 차이점을 이해하지 못했습니다.

나는 str().decode()당신이 알고있는 바이트 문자열이있을 때 특정 문자 인코딩을 가지고 있고, 인코딩 이름이 유니 코드 문자열을 반환한다는 것을 알고 있습니다.

unicode().encode()주어진 인코딩 이름에 따라 유니 코드 문자를 바이트 문자열로 변환 한다는 것을 알고 있습니다.

그러나 나는 무엇 str().encode()이고 무엇인지 이해하지 못합니다 unicode().decode(). 누구나 위에서 설명하고 잘못한 내용을 설명하고 수정할 수 있습니까?

편집하다:

여러 답변 .encode이 문자열에서 수행하는 작업 에 대한 정보를 제공 하지만 아무도 .decode유니 코드의 기능 을 아는 사람 이 없습니다 .


이 페이지 의 두 번째 대답은 충분히 명확하고 간결 하다고 생각합니다 .
Ben

답변:


106

decode유니 코드 문자열 의 방법에는 실제로 응용 프로그램이 전혀 없습니다 (어떤 이유로 유니 코드 문자열에 텍스트가 아닌 데이터가없는 경우는 제외하십시오-아래 참조). 그것은 역사적 이유로 주로 거기에 있다고 생각합니다. 파이썬 3에서는 완전히 사라졌습니다.

unicode().decode()기본 (ascii) 코덱 을 사용하여 암시 적 인코딩 을 수행합니다 s. 다음과 같이 확인하십시오.

>>> 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)

오류 메시지는 정확히 동일합니다.

들어 str().encode()는 주변의 다른 방법 - 그것은 암시 적 시도 디코딩s기본 인코딩을 :

>>> 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)

이렇게 사용하면 str().encode()불필요합니다.

그러나 유용한 후자의 방법의 또 다른 응용이 있습니다. 문자 세트와 관련이없는 인코딩 이 있으므로 8 비트 문자열에 의미있는 방식으로 적용 할 수 있습니다.

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

그러나 두 응용 프로그램 모두에 대한 "인코딩"의 모호한 사용법은 어색합니다. 또, 별도의과 bytestring파이썬 3의 유형이 더 이상 문제가되지 않습니다.


4
.decode()유니 코드 문자열에서 유용 할 수 있습니다.print u'\\u0203'.decode('unicode-escape')
jfs

python3의 @JFSebastian의 좋은 예 나는 당신이 할 것이라고 생각합니다 :print u'\\u0203'.encode('utf8').decode('unicode-escape')
AJP

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

@ 홉 : 예. 잘못된 입력을 감지하고 Python 2/3 호환성을 위해 문자열을 ascii인코딩을 사용하여 명시 적으로 인코딩 할 수 있습니다 .\\u0203\u00e4'.encode('ascii').decode('unicode-escape')
jfs

@hop : 첫 번째 의견 (왜 삭제 했습니까? 답장 한 댓글은 삭제하지 마십시오)이 이미 언급했습니다. 내 답변 ( .encode('ascii').decode('unicode-escape'))은에 의존하지 않습니다 sys.getdefaultencoding().
jfs

71

유니 코드 문자열을 바이트 문자열로 나타내는 것을 인코딩이라고 합니다. 사용하십시오 u'...'.encode(encoding).

예:

    >>> 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'코덱은 위치 0-5의 문자를 인코딩 할 수 없습니다 : 
    서 수가 범위를 벗어남 (128)

일반적으로 유니 코드 문자열을 IO에 사용해야 할 때마다 (예 : 네트워크를 통해 전송하거나 디스크 파일에 저장).

바이트 문자열을 유니 코드 문자열로 변환하는 것을 디코딩이라고 합니다. 사용 unicode('...', encoding)또는 '...'. 디코딩 (인코딩).

예:

   >>> u'æøå '
   u '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'# 인터프리터는 유니 코드 객체를 다음과 같이 인쇄합니다.
   >>> 유니 코드 ( '\ 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'

일반적으로 네트워크 또는 디스크 파일에서 문자열 데이터를 수신 할 때마다 바이트 문자열을 디코딩합니다.

파이썬 3에서 유니 코드 처리에 약간의 변화가 있다고 생각하므로 위의 내용은 파이썬 3에 맞지 않을 수 있습니다.

좋은 링크들 :


6
OP의 질문에 대답하지 않았습니다. OP는 str.encode () 및 unicode.decode ()의 기능을 알고 싶어합니다. 원래 질문에 언급 된 내용을 반복했습니다.
stuckintheshuck

실제로 왜 디코딩과 인코딩을 엉망으로 만들 었는지에 대한 훌륭한 대답. 모든 기계가 동일한 문자 세트를 이해하는 것은 아니지만 모두 바이트를 이해합니다. 컴퓨터가 보편적으로 이해하고 (디스크로 전송되거나 디스크에 저장 될 수있는) 언어를 위해 바이트로 인코딩하지만, 사람이 실제로 그 바이트를 읽어야 할 때 (예를 들어 클라이언트 쪽에서) 디코딩합니다.
Alex Petralia

환상적인 답변! 올라갑니다 !!
sandyp

16

유니 코드. encode ( 'encoding')는 문자열 객체를 생성하며 유니 코드 객체에서 호출 될 수 있습니다.

aString. 디코드 ( '인코딩')하면 유니 코드 객체가되며 주어진 인코딩으로 인코딩 된 문자열에서 호출 될 수 있습니다.


더 많은 설명 :

인코딩 세트가없는 유니 코드 객체를 만들 수 있습니다. 파이썬이 메모리에 저장하는 방식은 걱정할 필요가 없습니다. 검색, 분할 및 원하는 문자열 조작 함수를 호출 할 수 있습니다.

그러나 유니 코드 객체를 콘솔이나 텍스트 파일로 인쇄하려는 경우가 있습니다. 따라서 인코딩 해야합니다 (예 : UTF-8), encode ( 'utf-8')을 호출하면 내부에 '\ u <someNumber>'가있는 문자열이 생겨 완벽하게 인쇄 할 수 있습니다.

그런 다음 다시-UTF-8로 인코딩 된 반대로 읽은 문자열을 유니 코드로 취급하여 \ u360이 5가 아닌 하나의 문자가되도록하십시오. 그런 다음 문자열을 선택한 인코딩으로 디코딩 하고 유니 코드 유형의 새로운 객체를 얻습니다.

부수적으로- 'zip', 'base64', 'rot'과 같은 변태 인코딩을 선택할 수 있으며 그중 일부는 문자열에서 문자열로 변환되지만 가장 일반적인 경우는 UTF-8과 관련이 있다고 생각합니다 / UTF-16 및 문자열


12

mybytestring.encode (somecodec)는 다음 값에 의미가 있습니다 somecodec.

  • base64
  • bz2
  • zlib
  • 마녀
  • 쿼 프리
  • 썩음 13
  • string_escape
  • uu

이미 디코딩 된 유니 코드 텍스트를 디코딩하는 것이 어떤 것인지 잘 모르겠습니다. 인코딩으로 시도하면 항상 시스템의 기본 인코딩으로 먼저 인코딩하려고합니다.


5

str에서 str로 또는 유니 코드에서 유니 코드로 디코드 / 인코딩하는 데 사용할 수있는 몇 가지 인코딩이 있습니다. 예를 들어 base64, hex 또는 rot13입니다. 코덱 모듈에 나열되어 있습니다.

편집하다:

유니 코드 문자열의 디코드 메시지는 해당 인코딩 작업을 취소 할 수 있습니다.

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

반환 된 형식은 유니 코드 대신 str이며 불행히도 내 의견으로는 불행합니다. 그러나 str과 유니 코드 사이에서 적절한 인코딩 / 디코딩을 수행하지 않으면 어쨌든 혼란스럽게 보입니다.


1
-1 : 유니 코드 개체에 디코딩 방법이 적용되지 않습니다. 대신, 유니 코드 객체는 디코딩 작업이 시작되기 전에 'ascii'바이트 문자열로 인코딩됩니다. 그 주장의 증거를 위해, u'ã'.decode ( 'hex')를 시도하십시오-그러면 그것은 UnicodeEncodeError를 생성합니다
nosklo

2
@ nosklo : 당신이 맞아요. 내가 정말로 의미하는 것은 유니 코드 객체에 문자 인코딩이 아닌 코덱을 적용 할 수 있도록 decode () 메서드가 있다는 것입니다. 이 모든 비 문자-사업을 인코딩이 인터페이스 3. 파이썬 <의 혼란하게

1

간단한 대답은 그들이 서로 정반대라는 것입니다.

컴퓨터는 매우 기본적인 바이트 단위를 사용하여 정보를 저장하고 처리합니다. 인간의 눈에는 의미가 없습니다.

예를 들어, '\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87'은 두 개의 중국어 문자를 나타내지 만 컴퓨터는 사전을 제공받을 때만 중국어 문자를 인식 (인쇄 또는 저장)합니다. 이 경우 중국어 단어는 "utf-8"사전이며, 다른 디코딩 방법을 사용하여 다른 사전 또는 잘못된 사전을 보면 의도 한 중국어 단어를 올바르게 표시하지 못합니다.

위의 경우 컴퓨터에서 중국어 단어를 찾는 프로세스는 다음과 같습니다. decode() 입니다.

컴퓨터 메모리에 중국어를 쓰는 컴퓨터의 과정은 encode() .

따라서 인코딩 된 정보는 원시 바이트이고 디코딩 된 정보는 원시 바이트 및 참조 할 사전 이름 (사전 자체는 아님)입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.