在Python 2.6中不推荐使用BaseException.message

des*_*lat 168 python exception deprecated

当我使用以下用户定义的异常时,我收到一条警告,即在Python 2.6中不推荐使用BaseException.message:

class MyException(Exception):

    def __init__(self, message):
        self.message = message

    def __str__(self):
        return repr(self.message)
Run Code Online (Sandbox Code Playgroud)

这是警告:

DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message
Run Code Online (Sandbox Code Playgroud)

这有什么问题?我需要更改什么来摆脱弃用警告?

gee*_*ekQ 148

解决方案 - 几乎不需要编码

只需继承您的异常类,Exception并将消息作为第一个参数传递给构造函数

例:

class MyException(Exception):
    """My documentation"""

try:
    raise MyException('my detailed description')
except MyException as my:
    print my # outputs 'my detailed description'
Run Code Online (Sandbox Code Playgroud)

您可以使用str(my)或(不太优雅)my.args[0]来访问自定义消息.

背景

在较新版本的Python(从2.6)中,我们应该从Exception继承我们的自定义异常类(从Python 2.5开始)继承自BaseException.背景在PEP 352中详细描述.

class BaseException(object):

    """Superclass representing the base of the exception hierarchy.
    Provides an 'args' attribute that contains all arguments passed
    to the constructor.  Suggested practice, though, is that only a
    single string argument be passed to the constructor."""
Run Code Online (Sandbox Code Playgroud)

__str__并且__repr__已经以有意义的方式实现,特别是对于只有一个arg(可以用作消息)的情况.

您无需按照其他人的建议重复__str____init__实施或创建_get_message.

  • 如果使用unicode参数构造异常,则使用`str`中断:`str(MyException(u'\ xe5'))`引发`UnicodeEncodeError`.使用`unicode`而不是`str`也不是万无一失,因为`unicode(MyException('\ xe5'))`会引发UnicodeDecodeError.这是否意味着如果我事先不知道参数是`str`还是`unicode`,我必须使用`.args [0]`我以前使用`.message`? (7认同)
  • 根据@Matt的建议将BaseException更改为Exception (5认同)
  • @RyanP假设我实际上可以控制进入的内容.这是我面临的生活现实.我必须处理来自多个第三方库的异常.其中一些将unicode传递给他们的异常,一些传递str.其中一个库甚至有自己的类,它继承自unicode但有自己的repr方法,它返回unicode而不是spec所要求的str. (3认同)

Sah*_*has 26

是的,它在Python 2.6中已被弃用,因为它在Python 3.0中消失了

BaseException类不再提供存储错误消息的方法.你必须自己实现它.您可以使用使用属性存储消息的子类来执行此操作.

class MyException(Exception):
    def _get_message(self): 
        return self._message
    def _set_message(self, message): 
        self._message = message
    message = property(_get_message, _set_message)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助

  • 这有帮助,谢谢.现在发泄沮丧:ARGH!:) (3认同)
  • @vdboor:他正在使用`@ property`来禁用弃用警告. (2认同)

Max*_*yko 9

class MyException(Exception):

    def __str__(self):
        return repr(self.args[0])

e = MyException('asdf')
print e
Run Code Online (Sandbox Code Playgroud)

这是Python2.6风格的类.新异常需要任意数量的参数.


Aar*_*all 7

如何复制警告

让我澄清一下这个问题,因为无法用问题的示例代码复制这个问题,如果你打开了警告(通过-W标志,PYTHONWARNINGS环境变量或警告模块),这将在Python 2.6和2.7中复制警告:

>>> error = Exception('foobarbaz')
>>> error.message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
'foobarbaz'
Run Code Online (Sandbox Code Playgroud)

在使用时消除警告 .message

摆脱它的方法repr(error)是将内置异常子类化为Python设计者的意图:

>>> repr(error)
"Exception('foobarbaz',)"
Run Code Online (Sandbox Code Playgroud)

或者,避免使用该.message属性

但是,最好避免使用message属性,只需要DeprecationWarning处理错误.只是子类.message:

class MyException(Exception):

    def __init__(self, message, *args):
        self.message = message
        # delegate the rest of initialization to parent
        super(MyException, self).__init__(message, *args)

>>> myexception = MyException('my message')
>>> myexception.message
'my message'
>>> str(myexception)
'my message'
>>> repr(myexception)
"MyException('my message',)"
Run Code Online (Sandbox Code Playgroud)

用法:

class MyException(Exception):
    '''demo straight subclass'''
Run Code Online (Sandbox Code Playgroud)

另见这个答案:

在现代Python中声明自定义异常的正确方法?