Objek 'str' tidak memiliki atribut 'decode'. Kesalahan Python 3?


182

Ini kode saya:

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

pada titik ini saya mendapatkan pesan kesalahan

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

Python 3 tidak memiliki decode lagi, benarkan? bagaimana saya bisa memperbaikinya?

Juga di:

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

Saya hanya memilih email pertama. Bagaimana saya memilih semua?

Jawaban:


181

Anda mencoba memecahkan kode objek yang sudah diterjemahkan . Anda memiliki str, tidak perlu lagi men-decode dari UTF-8.

Cukup jatuhkan .decode('utf-8')bagian:

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

Sedangkan untuk fetch()panggilan Anda, Anda secara eksplisit meminta hanya pesan pertama. Gunakan rentang jika Anda ingin mengambil lebih banyak pesan. Lihat dokumentasi :

The message_set pilihan untuk perintah di bawah ini adalah string menentukan satu atau lebih pesan yang akan ditindaklanjuti. Ini bisa berupa nomor pesan sederhana ( '1'), rentang nomor pesan ( '2:4'), atau sekelompok rentang yang tidak berdekatan yang dipisahkan oleh koma ( '1:3,6:9'). Rentang dapat berisi tanda bintang untuk menunjukkan batas atas tak terbatas ( '3:*').


6
Apakah ada cara sederhana untuk melakukan ini secara kondisional? (Saya hanya ingin men-decode jika pesan dikodekan.)
devinbost

5
@devinbost: dalam Python 3? Tes untuk jenis objek atau decodeatribut, atau hanya menangkap pengecualian. try: data = data.decode('...') except AttributeError: pass.
Martijn Pieters

2
@devinbost: namun, Anda biasanya lebih baik mendekode lebih dekat ke sumber data Anda, di mana Anda biasanya akan tahu persis apa yang Anda miliki.
Martijn Pieters

37

Mulai dengan Python 3, semua string adalah objek unicode.

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

kode sebelumnya sama. Jadi saya pikir Anda harus menghapus .decode('utf-8'). Karena Anda sudah mendapatkan objek unicode.


37

Gunakan dengan Metode ini:

str.encode().decode()

1
bytearray(str, 'encoding').decode('another_encoding')akan melakukan pekerjaan jika Anda perlu memecahkan kode idnaatau pengkodean lainnya
Alex

20
Ini tidak berguna. Anda meng-encode ke UTF-8, lalu mendekode byte yang dihasilkan sebagai UTF-8, berakhir di tempat Anda mulai. Anda menjaga kehangatan CPU tanpa manfaat lain.
Martijn Pieters

1
@MartijnPieters "berakhir di tempat Anda mulai" - tidak jika Anda memiliki urutan melarikan diri dalam string Anda, misalnya: >>> '\ u0159'.encode (). Decode ()' decode () 'ř'
Peter

1
@ Peter: tidak, Anda tidak perlu melakukan encoding atau decoding untuk itu. '\u0159'mencetak hasil yang sama persis. Anda mengacaukan sintaks literal string dengan representasi kanonik nilai.
Martijn Pieters

2
Anda dapat langsung menggunakan, Tidak perlu untuk menyandikan lalu mendekode lagi.
Aditya

10

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

Aku sangat mencintaimu!
Gal Shahar

8

Saya tidak terbiasa dengan pustaka, tetapi jika masalah Anda adalah Anda tidak ingin array byte, satu cara mudah adalah dengan menentukan jenis pengkodean langsung dalam gips:

>>> my_byte_str
b'Hello World'

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

Mereka tidak memiliki bytesobjek untuk memulai, dan str(bytes_object, codec)hanya ejaan alternatif untuk bytes_object.decode(codec). Keduanya gagal jika Anda benar-benar memilikinya str.
Martijn Pieters

1
Anda benar, pertanyaan spesifik ini memang strsudah ada. Jawaban ini masih bisa bermanfaat bagi orang-orang di masa depan yang mungkin memiliki array byte (ini adalah masalah yang saya hadapi ketika saya awalnya menemukan posting ini).
Broper

Saya tidak yakin bagaimana Anda menemukan posting ini, karena my_byte_str.decodeada dan berfungsi, dan tidak akan melempar pengecualian dalam pertanyaan.
Martijn Pieters

3

Sudah diterjemahkan dalam Python3, Coba langsung itu harus bekerja.


1
Terima kasih @Aditya Alasan saya tiba di sini adalah karena beralih kode dengan 2to3
Jesse Reza Khorasanee

0

Jawaban lain semacam mengisyaratkan itu, tetapi masalah mungkin timbul dari mengharapkan objek byte. Dalam Python 3, decode valid ketika Anda memiliki objek byte kelas. Menjalankan penyandian sebelum decode dapat "memperbaiki" masalah, tetapi itu adalah sepasang operasi yang tidak berguna yang menyarankan masalah kita ke hulu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.