pythonのe.message

5900 ワード

最近では,Exception処理時にe.messageを用いて異常(エラー)情報を出力している人もいることが分かった.
プログラムの例(ログ):
[E 170831 21:24:33 handler:199] [CRP] Get azuop_hypervisors_statistics err: ('list index out of range',)
    Traceback (most recent call last):
      File "/opt/crp-backend/crp/availability_zone/handler.py", line 175, in get
        hosts = zones[0].hosts.keys()
    IndexError: list index out of range
/opt/crp-backend/crp/availability_zone/handler.py:205: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
  "msg": e.message
[W 170831 21:24:33 wsgi:355] 400 GET /api/az/uopStatistics (172.28.26.199) 1434.54ms
今Pythonの最新バージョンはpython 2です.7.13/python3.6.2、e.messageはpython 2である.5.xの文法です.
おすすめの書き方は、
  • e.messageからe.args
  • に変更する.
    1つのtupleを返し、情報が空の場合、空のtupleを返します.()
  • Exceptionをカスタマイズし、messageのプロパティを実現します.
  • インタラクティブコマンドラインのデバッグを使用します.
    
    $ ipython
    Python 2.7.5 (default, Nov  6 2016, 00:28:07)
    Type "copyright", "credits" or "license" for more information.
    
    IPython 5.0.0 -- An enhanced Interactive Python.
    ?         -> Introduction and overview of IPython's features.
    %quickref -> Quick reference.
    help      -> Python's own help system.
    object?   -> Details about 'object', use 'object??' for extra details.
    
    In [1]: error = Exception('foobarbaz')
    
    In [2]: error.message
    /bin/ipython:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
      #!/usr/bin/python
    Out[2]: 'foobarbaz'
    
    In [3]: error.args
    Out[3]: ('foobarbaz',)
    
    In [4]: error = Exception()
    
    In [5]: error.message
    /bin/ipython:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
      #!/usr/bin/python
    Out[5]: ''
    
    In [6]: error.args
    Out[6]: ()
    
    
    拡張読書
    PEP 352 -- Required Superclass for Exceptions https://www.python.org/dev/peps/pep-0352/概要:
    Here is BaseException as implemented in the 2.x series:
    
    class BaseException(object):
    
        """Superclass representing the base of the exception hierarchy.
    
        The __getitem__ method is provided for backwards-compatibility
        and will be deprecated at some point.  The 'message' attribute
        is also deprecated.
    
        """
    
        def __init__(self, *args):
            self.args = args
    
        def __str__(self):
            return str(self.args[0]
                       if len(self.args) <= 1
                       else self.args)
    
        def __repr__(self):
            func_args = repr(self.args) if self.args else "()"
            return self.__class__.__name__ + func_args
    
        def __getitem__(self, index):
            """Index into arguments passed in during instantiation.
    
            Provided for backwards-compatibility and will be
            deprecated.
    
            """
            return self.args[index]
    
        def _get_message(self):
            """Method for 'message' property."""
            warnings.warn("the 'message' attribute has been deprecated "
                            "since Python 2.6")
            return self.args[0] if len(args) == 1 else ''
    
        message = property(_get_message,
                            doc="access the 'message' attribute; "
                                "deprecated and provided only for "
                                "backwards-compatibility")
    
    Deprecation of features in Python 2.9 is optional. This is because it is not known at this time if Python 2.9 (which is slated to be the last version in the 2.x series) will actively deprecate features that will not be in 3.0. It is conceivable that no deprecation warnings will be used in 2.9 since there could be such a difference between 2.9 and 3.0 that it would make 2.9 too "noisy" in terms of warnings. Thus the proposed deprecation warnings for Python 2.9 will be revisited when development of that version begins, to determine if they are still desired.
    
    
    DeprecationWarning: BaseException.message has been deprecated as of Python 2.6 exception.class, exception.message, https://stackoverflow.com/questions/13063212/deprecationwarning-baseexception-message-has-been-deprecated-as-of-python-2-6-e
    概要:
    If I remember correctly, when Python switched to the new raise syntax in 2.5(?), they got rid of the message member in favor of an args tuple. For backward compatibility, BaseException.message is effectively the same thing as BaseException.args[0] if BaseException.args else None, but you shouldn't use it in new code.
    
    So, change message to either args (if you want all args) or args[0] (or, if you're worried there may be no args, the fancier version that protects against ()), depending on which you want.
    
    The reason for this change is that with the new-style exceptions, there's no magic to raise or except anymore; you're just calling the exception class's constructor in the raise statement, and catching the exception in a variable in the except statement. So:
    
    try:
      raise MyException('Out of cheese error', 42)
    except Exception as x:
      print x.args
    This will print ('Out of cheese error', 42). If you only had print x.message you'd just get 'Out of cheese error'. So, the Exception subclasses that used to have to do fancy things to carry around an error code as a separate member, etc., can be simplified; in fact, the whole thing comes down to this:
    
    class BaseException(object):
      def __init__(self, *args):
        self.args = args
    
    Proper way to declare custom exceptions in modern Python? https://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python/26938914#26938914
    BaseException.message deprecated in Python 2.6