'str'오브젝트에는 'decode'속성이 없습니다. 파이썬 3 오류?


182

내 코드는 다음과 같습니다.

import imaplib
from email.parser import HeaderParser

conn = imaplib.IMAP4_SSL('imap.gmail.com')
conn.login('example@gmail.com', 'password')
conn.select()
conn.search(None, 'ALL')
data = conn.fetch('1', '(BODY[HEADER])')
header_data = data[1][0][1].decode('utf-8')

이 시점에서 오류 메시지가 나타납니다.

AttributeError: 'str' object has no attribute 'decode'

파이썬 3는 더 이상 해독하지 않습니다. 이 문제를 어떻게 해결할 수 있습니까?

또한

data = conn.fetch('1', '(BODY[HEADER])')

첫 번째 이메일 만 선택하고 있습니다. 모두 선택하려면 어떻게합니까?

답변:


181

이미 디코딩 된 객체를 디코딩하려고합니다 . 당신은 str더 이상 UTF-8에서 디코딩 할 필요가 없습니다.

.decode('utf-8')부품을 간단히 떨어 뜨립니다 .

header_data = data[1][0][1]

당신의 fetch()전화에 관해서 , 당신은 명시 적으로 첫 번째 메시지를 요구하고 있습니다. 더 많은 메시지를 검색하려면 범위를 사용하십시오. 설명서를 참조하십시오 :

아래의 명령에 대한 message_set 옵션은 수행 할 하나 이상의 메시지를 지정하는 문자열입니다. 간단한 메시지 번호 ( '1'), 메시지 번호 범위 ( '2:4') 또는 쉼표 ( '1:3,6:9') 로 구분 된 비 연속 범위 그룹 일 수 있습니다. 범위에는 무한한 상한 ( '3:*') 을 나타내는 별표가 포함될 수 있습니다 .


6
조건부로 이것을 수행하는 간단한 방법이 있습니까? (메시지가 인코딩 된 경우에만 디코딩하고 싶습니다.)
devinbost

5
@ devinbost : Python 3에서? 객체 유형이나 decode속성을 테스트 하거나 예외를 잡아라. try: data = data.decode('...') except AttributeError: pass.
Martijn Pieters

2
@devinbost : 그러나 일반적으로 데이터 소스에 더 가깝게 디코딩하는 것이 좋습니다.
Martijn Pieters

37

파이썬 3부터 모든 문자열은 유니 코드 객체입니다.

  a = 'Happy New Year' # Python 3
  b = unicode('Happy New Year') # Python 2

이전 코드는 동일합니다. 따라서을 제거해야한다고 생각합니다 .decode('utf-8'). 이미 유니 코드 객체를 얻었 기 때문입니다.


37

이 방법으로 사용하십시오.

str.encode().decode()

1
bytearray(str, 'encoding').decode('another_encoding')디코딩 idna이나 다른 인코딩 이 필요한 경우 작업을 수행합니다
Alex

20
이것은 쓸모가 없습니다. UTF-8로 인코딩 한 다음 결과 바이트를 UTF-8로 디코딩하여 시작한 위치로 끝납니다. 다른 이점없이 CPU를 따뜻하게 유지하고 있습니다.
Martijn Pieters

1
@MartijnPieters "시작 위치"-문자열에 이스케이프 시퀀스가없는 경우 (예 : >>> '\ u0159'.encode (). decode ()'ř '
Peter

1
@Peter : 아니요, 인코딩이나 디코딩이 필요하지 않습니다. '\u0159'정확히 동일한 출력을 인쇄합니다. 문자열 리터럴 구문과 값의 표준 표현을 혼동하고 있습니다.
Martijn Pieters

2
직접 사용할 수 있으므로 인코딩 한 다음 다시 디코딩 할 필요가 없습니다.
Aditya

10

Python3의 경우

html = """\\u003Cdiv id=\\u0022contenedor\\u0022\\u003E \\u003Ch2 class=\\u0022text-left m-b-2\\u0022\\u003EInformaci\\u00f3n del veh\\u00edculo de patente AA345AA\\u003C\\/h2\\u003E\\n\\n\\n\\n \\u003Cdiv class=\\u0022panel panel-default panel-disabled m-b-2\\u0022\\u003E\\n \\u003Cdiv class=\\u0022panel-body\\u0022\\u003E\\n \\u003Ch2 class=\\u0022table_title m-b-2\\u0022\\u003EInformaci\\u00f3n del Registro Automotor\\u003C\\/h2\\u003E\\n \\u003Cdiv class=\\u0022col-md-6\\u0022\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003ERegistro Seccional\\u003C\\/label\\u003E\\n \\u003Cp\\u003ESAN MIGUEL N\\u00b0 1\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EDirecci\\u00f3n\\u003C\\/label\\u003E\\n \\u003Cp\\u003EMAESTRO ANGEL D\\u0027ELIA 766\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EPiso\\u003C\\/label\\u003E\\n \\u003Cp\\u003EPB\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EDepartamento\\u003C\\/label\\u003E\\n \\u003Cp\\u003E-\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EC\\u00f3digo postal\\u003C\\/label\\u003E\\n \\u003Cp\\u003E1663\\u003C\\/p\\u003E\\n \\u003C\\/div\\u003E\\n \\u003Cdiv class=\\u0022col-md-6\\u0022\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003ELocalidad\\u003C\\/label\\u003E\\n \\u003Cp\\u003ESAN MIGUEL\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EProvincia\\u003C\\/label\\u003E\\n \\u003Cp\\u003EBUENOS AIRES\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003ETel\\u00e9fono\\u003C\\/label\\u003E\\n \\u003Cp\\u003E(11)46646647\\u003C\\/p\\u003E\\n \\u003Clabel class=\\u0022control-label\\u0022\\u003EHorario\\u003C\\/label\\u003E\\n \\u003Cp\\u003E08:30 a 12:30\\u003C\\/p\\u003E\\n \\u003C\\/div\\u003E\\n \\u003C\\/div\\u003E\\n\\u003C\\/div\\u003E \\n\\n\\u003Cp class=\\u0022text-center m-t-3 m-b-1 hidden-print\\u0022\\u003E\\n \\u003Ca href=\\u0022javascript:window.print();\\u0022 class=\\u0022btn btn-default\\u0022\\u003EImprim\\u00ed la consulta\\u003C\\/a\\u003E \\u0026nbsp; \\u0026nbsp;\\n \\u003Ca href=\\u0022\\u0022 class=\\u0022btn use-ajax btn-primary\\u0022\\u003EHacer otra consulta\\u003C\\/a\\u003E\\n\\u003C\\/p\\u003E\\n\\u003C\\/div\\u003E"""
print(html.replace("\\/", "/").encode().decode('unicode_escape'))

널 너무나도 사랑해!
Gal Shahar

8

나는 라이브러리에 익숙하지 않지만 문제가 바이트 배열을 원하지 않는다면 캐스트에서 인코딩 유형을 직접 지정하는 것이 가장 쉬운 방법입니다.

>>> my_byte_str
b'Hello World'

>>> str(my_byte_str, 'utf-8')
'Hello World'

그들은 bytes시작할 객체 가 없으며에 str(bytes_object, codec)대한 대체 철자입니다 bytes_object.decode(codec). 실제로 str대신에 두 가지 모두 실패합니다 .
Martijn Pieters

1
당신이 옳습니다.이 특정 질문에는 str이미 있습니다. 이 답변은 바이트 배열이있을 수있는 미래의 사람들에게 여전히 유용 할 수 있습니다 (이것은 원래이 게시물을 우연히 만났을 때 직면 한 문제였습니다).
Broper

그러나이 게시물에서 어떻게 우연히 발견되었는지 잘 모르겠습니다. 왜냐하면 my_byte_str.decode존재하고 작동 하기 때문에 질문에 예외가 발생하지 않기 때문 입니다.
Martijn Pieters

3

이미 Python3에서 디코딩되었으므로 직접 시도해보십시오.


1
내가 여기에 도착 이유 @Aditya 감사 때문에 2to3로 코드를 전환입니다
제시 레자 Khorasanee을

0

다른 답변은 일종의 힌트이지만 바이트 객체를 기대하면 문제가 발생할 수 있습니다. Python 3에서는 클래스 바이트의 객체가있는 경우 디코드가 유효합니다. 디코딩하기 전에 인코딩을 실행하면 문제가 "수정"될 수 있지만, 업스트림에 문제가 있음을 나타내는 것은 쓸모없는 작업 쌍입니다.

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