L'oggetto 'str' non ha attributo 'decodifica'. Errore Python 3?


182

Ecco il mio codice:

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

a questo punto ricevo il messaggio di errore

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

Python 3 non ha più la decodifica, vero? come posso risolvere questo?

Anche in:

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

Sto selezionando solo la prima e-mail. Come seleziono tutto?

Risposte:


181

Stai tentando di decodificare un oggetto che è già decodificato . Hai un str, non è più necessario decodificare da UTF-8.

Rilascia semplicemente la .decode('utf-8')parte:

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

Per quanto riguarda la tua fetch()chiamata, stai chiedendo esplicitamente solo il primo messaggio. Utilizzare un intervallo se si desidera recuperare più messaggi. Vedi la documentazione :

Le opzioni message_set ai comandi seguenti sono una stringa che specifica uno o più messaggi su cui agire. Può essere un semplice numero di messaggio ( '1'), un intervallo di numeri di messaggio ( '2:4') o un gruppo di intervalli non contigui separati da virgole ( '1:3,6:9'). Un intervallo può contenere un asterisco per indicare un limite superiore infinito ( '3:*').


6
C'è un modo semplice per farlo condizionatamente? (Voglio decodificare solo se il messaggio è codificato.)
Devinbost

5
@devinbost: in Python 3? Verifica il tipo di oggetto o l' decodeattributo o rileva semplicemente l'eccezione. try: data = data.decode('...') except AttributeError: pass.
Martijn Pieters

2
@devinbost: tuttavia, di solito è meglio decodificare più vicino alla fonte dei dati, dove di solito saprai esattamente cosa hai.
Martijn Pieters

37

Inizia con Python 3, tutta la stringa è un oggetto Unicode.

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

il codice prima è lo stesso. Quindi penso che dovresti rimuovere il file .decode('utf-8'). Perché hai già ottenuto l'oggetto Unicode.


37

Usalo con questo metodo:

str.encode().decode()

1
bytearray(str, 'encoding').decode('another_encoding')farebbe il lavoro se dovessi decodificare idnao qualsiasi altra codifica
Alex

20
Questo è inutile. Stai codificando in UTF-8, quindi decodificando i byte risultanti come UTF-8, finendo da dove hai iniziato. Stai mantenendo la CPU calda senza altri vantaggi.
Martijn Pieters

1
@MartijnPieters "finendo dove hai iniziato" - non se hai sequenze di escape nella tua stringa, ad esempio: >>> '\ u0159'.encode (). Decode ()' ř '
Peter

1
@Peter: no, non hai bisogno di codifica o decodifica per questo. '\u0159'stampa esattamente lo stesso risultato. Stai confondendo la sintassi letterale di stringa con la rappresentazione canonica del valore.
Martijn Pieters

2
È possibile utilizzare direttamente, Non è necessario codificare e quindi decodificare nuovamente.
Aditya,

10

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

Ti amo tanto!
Gal Shahar,

8

Non ho familiarità con la libreria, ma se il tuo problema è che non vuoi un array di byte, un modo semplice è specificare un tipo di codifica direttamente in un cast:

>>> my_byte_str
b'Hello World'

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

Non hanno un bytesoggetto per cominciare, ed str(bytes_object, codec)è solo un'ortografia alternativa per bytes_object.decode(codec). Entrambi falliscono se hai davvero un strinvece.
Martijn Pieters

1
Hai ragione, questa domanda specifica ha strgià un . Questa risposta potrebbe essere ancora utile per le persone in futuro che potrebbero avere array di byte (questo era il problema che ho affrontato quando mi sono imbattuto in questo post).
Broper,

Non sono sicuro di come ti sia imbattuto in questo post, tuttavia, perché my_byte_str.decodeesiste e funziona e non getterà l'eccezione nella domanda.
Martijn Pieters

3

È già decodificato in Python3, prova direttamente che dovrebbe funzionare.


1
Grazie @Aditya Il motivo per cui sono arrivato qui è a causa del cambio di codice con 2to3
Jesse Reza Khorasanee

0

Altre risposte suggeriscono qualcosa, ma il problema potrebbe derivare dall'aspettarsi un oggetto byte. In Python 3, la decodifica è valida quando si dispone di un oggetto di byte di classe. L'esecuzione della codifica prima della decodifica può "risolvere" il problema, ma è una coppia inutile di operazioni che suggerisce il problema a monte.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.