'str'对象没有属性'decode'.Python 3错误?

149 python imaplib python-3.x

这是我的代码:

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')
Run Code Online (Sandbox Code Playgroud)

此时我收到错误消息

AttributeError: 'str' object has no attribute 'decode'
Run Code Online (Sandbox Code Playgroud)

Python 3不再有解码,我是对的吗?我怎样才能解决这个问题?

另外,在:

data = conn.fetch('1', '(BODY[HEADER])')
Run Code Online (Sandbox Code Playgroud)

我只选择第一封电子邮件.我该如何选择全部?

Mar*_*ers 154

您正在尝试解码已解码的对象.你有一个str,不再需要从UTF-8解码.

只需放下.decode('utf-8')部件:

header_data = data[1][0][1]
Run Code Online (Sandbox Code Playgroud)

至于你的fetch()电话,你明确要求第一条消息.如果要检索更多消息,请使用范围.查看文档:

以下命令的message_set选项是一个字符串,指定要对其执行操作的一条或多条消息.它可以是简单的消息号('1'),一系列消息号('2:4'),或由逗号('1:3,6:9')分隔的一组非连续范围.范围可以包含星号以指示无限上限('3:*').

  • 有条件地做一个简单的方法吗?(我只想解码消息是否被编码.) (5认同)
  • @devinbost:在Python 3中?测试对象类型或`decode`属性,*或*只是捕获异常.`try:data = data.decode('...')除了AttributeError:pass`. (5认同)
  • @devinbost:但是,通常最好在靠近数据源的地方解码,通常您会确切地知道自己拥有什么。 (2认同)

Mat*_*let 44

如果您在 PyJWT v2.0.0 版本 (22/12/2020) 之后使用 jwt 身份验证登陆此处,您可能希望将您的 PyJWT 版本冻结到requirements.txt文件中的先前版本。

PyJWT==1.7.1
Run Code Online (Sandbox Code Playgroud)

  • 给这个人一枚奖章!!!!这是我们环境中的“rest_framework_simplejwt”包的依赖项,并导致了问题。 (9认同)
  • 这不是一个安全的解决方案:请参阅影响 PyJWT 1.x 版本的 CVE-2022-29217:https://github.com/jpadilla/pyjwt/security/advisories/GHSA-ffqj-6fqr-9h24 (3认同)

Fli*_*imm 33

在 Python 3 中,这种思维模型非常简单:

\n
    \n
  • 编码str是将a转换为bytes对象的过程
  • \n
  • 解码bytes是将对象转换为对象的过程str
  • \n
\n
\xe2\x94\x8f\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x93                \xe2\x94\x8f\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x93\n\xe2\x94\x83       \xe2\x94\x83 -> encoding -> \xe2\x94\x83       \xe2\x94\x83\n\xe2\x94\x83  str  \xe2\x94\x83                \xe2\x94\x83 bytes \xe2\x94\x83\n\xe2\x94\x83       \xe2\x94\x83 <- decoding <- \xe2\x94\x83       \xe2\x94\x83\n\xe2\x94\x97\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x9b                \xe2\x94\x97\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x81\xe2\x94\x9b\n
Run Code Online (Sandbox Code Playgroud)\n

在您的情况下,您正在调用data.decode("UTF-8"),但变量已经是一个str对象并且已经被解码。data所以如果你需要一个字符串,直接引用即可。

\n


Neo*_* Ko 30

从Python 3开始,所有字符串都是unicode对象.

  a = 'Happy New Year' # Python 3
  b = unicode('Happy New Year') # Python 2
Run Code Online (Sandbox Code Playgroud)

以前的代码是一样的.所以我认为你应该删除.decode('utf-8').因为你已经获得了unicode对象.


Ali*_*eza 28

使用此方法:

str.encode().decode()
Run Code Online (Sandbox Code Playgroud)

  • 这没用.您正在编码为UTF-8,然后将生成的字节解码为UTF-8,最终到达您开始的位置.你保持CPU温暖,没有其他好处. (9认同)
  • @Peter:不,您不需要为此编码或解码。`'\u0159'` 打印出完全相同的输出。您将字符串文字语法与值的规范表示混淆了。 (3认同)
  • `bytearray(str, 'encoding').decode('another_encoding')` 如果你需要解码 `idna` 或任何其他编码,就可以完成这项工作 (2认同)
  • @MartijnPieters“在你开始的地方结束” - 如果你的字符串中有转义序列,则不会,例如: &gt;&gt;&gt; '\u0159'.encode().decode() 'ř' (2认同)
  • 您可以直接使用,无需编码,然后再次解码。 (2认同)

小智 15

对于 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"""
Run Code Online (Sandbox Code Playgroud)
print(html.replace("\\/", "/").encode().decode('unicode_escape'))
Run Code Online (Sandbox Code Playgroud)

  • 这和问题有什么关系?你能解释一下你的答案是做什么的吗? (3认同)

Bro*_*per 6

我不熟悉该库,但是如果您的问题是您不想要字节数组,则一种简单的方法是直接在类型转换中指定编码类型:

>>> my_byte_str
b'Hello World'

>>> str(my_byte_str, 'utf-8')
'Hello World'
Run Code Online (Sandbox Code Playgroud)


Adi*_*tya 5

它已经在Python3中解码了,直接尝试它应该可以工作。


小智 5

这对我有用:

html.replace("\\/", "/").encode().decode('unicode_escape', 'surrogatepass')
Run Code Online (Sandbox Code Playgroud)

这类似于 json.loads(html) 行为