如何将类似字符串的字节转换为普通字节?

时间:2019-08-18 10:04:52

标签: python python-3.x string byte imapclient

imapclient-库的异常处理过程中,我遇到了问题。

我试图这样处理LoginError:

source = IMAPClient(host=args.source_server, port=args.source_port, ssl=not args.source_no_ssl)

try:
    print('Login source...'.format(args.source_user), end='', flush=False)
    source.login(args.source_user, args.source_pass)
    print('OK')

except exceptions.LoginError as e:
    print('ERROR: {}'.format(e))
    exit()

如果有例外,我已经知道了:

Login source...ERROR: b'Invalid login'

我认为问题是format正在调用Exception-object的__str__()方法,并且不要尝试解码。

所以主要问题是谁可以转换此字符串

"b'Invalid login'"

像这样的普通字节对象?

b'Invalid login'

编辑1

@lenik 如果我这样使用e.message.decode()

try:
    print('Login source...'.format(args.source_user), end='', flush=False)
    source.login(args.source_user, args.source_pass)
    print('OK')
except exceptions.LoginError as e:
    print('ERROR: {}'.format(e.message.decode()))
    exit()

我遇到了AttributeError:

AttributeError: 'LoginError' object has no attribute 'message'

编辑2

@snakecharmerb

try:
    print('Login source...'.format(args.source_user), end='', flush=False)
    source.login(args.source_user, args.source_pass)
    print('OK')
except exceptions.LoginError as e:
    print('ERROR: {}'.format(e.args[0].decode()))
    exit()
AttributeError: 'str' object has no attribute 'decode'

3 个答案:

答案 0 :(得分:1)

imapclient的登录方法类似于this

def login(self, username, password):
    """Login using *username* and *password*, returning the
    server response.
    """
    try:
        rv = self._command_and_check(
            'login',
            to_unicode(username),
            to_unicode(password),
            unpack=True,
        )
    except exceptions.IMAPClientError as e:
        raise exceptions.LoginError(str(e))

    logger.info('Logged in as %s', username)
return rv

我们可以看到它在str上调用了IMAPClientError,因此,如果IMAPClientError是用bytes实例作为其参数创建的,那么我们最终会在{ {1}} *

有两种处理方法:

  1. 通过异常的LoginError元组访问原始字节:

args

  1. 使用ast.literal_eval转换字符串化的异常:

msg = e.args[0].decode()

在这两种方法中,我认为(1)在此特定情况下更好,但(2)在具有字符串字节的情况下更适用。


* 查看github上imaplib模块的历史,似乎它更改为显式解码错误消息,然后再从Python 3.5中的authenticate命令引发错误。因此,另一个解决方案可能是升级到Python 3.5 +。

答案 1 :(得分:1)

  1. 代表“ b'xx'”-> b'xx'
>>> s = "b'a'"
>>> eval(s)
b'a'
  1. 您可以使用print('dir(e): {}'.format(dir(e)))查看属性,或将其腌制到文件中并将其加载到ipython中进行解析。

答案 2 :(得分:0)

您是否尝试过这样做:

>>> a = b'invalid'
>>> a
b'invalid'
>>> a.decode()
'invalid'


好,第二次服用

>>> import imaplib
>>> dir(imaplib.IMAP4.error)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', 'args', 'message']
>>> imaplib.IMAP4.error.message
<attribute 'message' of 'exceptions.BaseException' objects>

似乎应该在那里有一个message,因为根据消息来源,LoginError似乎是imaplib.IMAP4.error的后代:https://imapclient.readthedocs.io/en/2.1.0/_modules/imapclient/exceptions.html#LoginError

您可能希望在捕获异常的地方打印dir(e)以查看其内容-__str__()应该将某些内容转换为字节字符串。


然后再次进行有关IMAP4和IMAPClient库的对话,并在此处捕获异常:Catching imaplib exception (using IMAPClient package) in Python