Frage

Ich erhalte eine Warnung, dass BaseException.message in Python 2.6 ist veraltet, wenn ich die folgende benutzerdefinierte Ausnahme verwenden:

class MyException(Exception):

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

    def __str__(self):
        return repr(self.message)

Dies ist die Warnung:

DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message

Was ist daran falsch? Was muss ich ändern der deprecation Warnung loswerden?

War es hilfreich?

Lösung

Lösung - fast keine Codierung benötigt

Just erben Ihre Ausnahmeklasse von Exception und die Nachricht als ersten Parameter an den Konstruktor übergeben

Beispiel:

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

try:
    raise MyException('my detailed description')
except MyException as my:
    print my # outputs 'my detailed description'

Sie können mit str(my) oder (weniger elegant) my.args[0] die benutzerdefinierte Nachricht zuzugreifen.

Hintergrund

In den neueren Versionen von Python (ab 2.6) sollen wir unsere eigenen Ausnahmeklassen von Exception, die ( ausgehend von Python 2.5 ) erbt von BaseException. Der Hintergrund wird im Detail beschrieben in 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."""

__str__ und __repr__ sind bereits in einer sinnvollen Art und Weise umgesetzt, insbesondere für den Fall nur eine arg (das als Nachricht verwendet werden kann).

Sie brauchen nicht __str__ oder __init__ Implementierung zu wiederholen oder _get_message erstellen, wie von anderen vorgeschlagen.

Andere Tipps

Ja, es ist in Python veraltete 2.6, weil es geht weg in Python 3.0

BaseException Klasse bietet keine Möglichkeit mehr Fehlermeldung zu speichern. Sie werden es selbst implementieren müssen. Sie können dies tun mit einer Unterklasse, die eine Eigenschaft zum Speichern der Nachricht verwendet.

class MyException(Exception):
    def _get_message(self): 
        return self._message
    def _set_message(self, message): 
        self._message = message
    message = property(_get_message, _set_message)

Hope, das hilft

class MyException(Exception):

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

e = MyException('asdf')
print e

Das ist Ihre Klasse in python2.6 Stil. Die neue Ausnahme nimmt eine beliebige Anzahl von Argumenten.

Wie die Warnung

replizieren

Lassen Sie mich das Problem klären, wie man dies nicht replizieren kann mit der Beispielcode Frage, dies die Warnung in Python replizieren 2.6 und 2.7, wenn Sie Warnungen eingeschaltet haben (über das -W Flagge , die PYTHONWARNINGS Umgebungsvariable oder die Warnungen Modul ):

>>> error = Exception('foobarbaz')
>>> error.message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
'foobarbaz'
Stopp

.message mit

Ich ziehe repr(error), die einen String zurückgibt, der den Namen des Fehlertyp enthält, die repr der Nachricht, wenn es eine gibt, und die repr der übrigen Argumente ist.

>>> repr(error)
"Exception('foobarbaz',)"

Die Beseitigung der Warnung, während immer noch .message mit

Und die Art und Weise Sie get rid von der DeprecationWarning ist eine builtin Ausnahme Unterklasse wie die Python-Designer gedacht:

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

immer nur das .message Attribut ohne error.message

Wenn Sie wissen, dass es war ein Argument, eine Nachricht, auf die Ausnahme, und das ist, was Sie wollen, ist es vorzuziehen, die Nachricht Attribut zu vermeiden und nehmen Sie nur den str des Fehlers. Sprich für eine subclassed Exception:

class MyException(Exception):
    '''demo straight subclass'''

Und Nutzung:

>>> myexception = MyException('my message')
>>> str(myexception)
'my message'

Siehe auch diese Antwort:

Richtige Art und Weise kundenspezifische Ausnahmen zu erklären, in moderner Python?

Soweit ich das beurteilen kann, einfach einen anderen Namen für die Nachrichten Attribut vermeidet den Konflikt mit der Basisklasse, und somit stoppt die deprecation Warnung:

class MyException(Exception):

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

def __str__(self):
    return repr(self.msg)

Es scheint wie ein Hack zu mir.

Vielleicht kann mir jemand erklären, warum die Warnung auch ausgegeben, wenn die Unterklasse eine Nachricht explizit Attribut definiert. Wenn die Basisklasse nicht mehr dieses Attribut hat, sollte es kein Problem sein.

Anknüpfend an geekQ Antwort hängt der bevorzugte Code Ersatz, was Sie tun müssen:

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

try:
    raise MyException('my detailed description')
except MyException as my:
    ### Solution 1, fails in Python 2.x if MyException contains 🔥
    # with UnicodeEncodeError: 'ascii' codec can't encode characters in position 24-25: ordinal not in range(128)
    print(my)  # outputs 'my detailed description'

### Solution 2
# Works in Python 2.x if exception only has ASCII characters,
# should always work in Python 3.x
str(my)

### Solution 3
# Required in Python 2.x if you need to handle non-ASCII characters,
# such as δσφφδσ (as pointed out by jjc) or emoji 🔥 💕 🎁 💯 🌹
# but does not work in Python 3.x
unicode(my)

Manchmal Ausnahmen haben mehr als ein Argument, so wird my.args[0] nicht bieten, um alle relevanten Informationen gewährleistet.

Zum Beispiel:

# Python 2.7
try:
    u'\u12345'.encode('utf-8').encode('utf-8')
except UnicodeDecodeError as e:
    print e.args[0]
    print e.args
    print str(e)

Druck als Ausgabe:

ascii
('ascii', '\xe1\x88\xb45', 0, 1, 'ordinal not in range(128)')
'ascii' codec can't decode byte 0xe1 in position 0: ordinal not in range(128)

Allerdings ist es ein kontextsensitive Trade-off, weil zum Beispiel:

# Python 2.7
>>> str(SyntaxError())
'None'
# 'None' compares True which might not be expected

Der Rat str (MyException) führt zu Unicode Problemen in Python 2.7, z zu verwenden:.

str(Exception(u'δσφφδσ'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

(

unicode(Exception(u'δσφφδσ')) 

funktioniert wie erwartet, und wird in Fällen bevorzugt, bei denen ein Teil des Inhalts des Fehlerstring Benutzereingabe enthält

pzrq der Post sagt zu verwenden:

str(e)

Das war genau das, was ich brauchte.

(Wenn Sie in einer Unicode-Umgebung sind, scheint es, dass:

unicode(e)

wird funktionieren, und es scheint, in einer Nicht-Unicode-Umgebung zu funktionieren)

Pzrq sagte eine Menge anderer guter Sachen, aber ich fast verpasst ihre Antwort wegen all der guten Sachen. Da ich mich nicht kommentieren 50 Punkte habe, kann nicht auf ihrer Antwort zu versuchen, die Aufmerksamkeit auf die einfache Lösung zu zeichnen, das funktioniert, und da ich mir nicht 15 haben kann, dass die Abstimmung nicht beantworten, aber ich kann schreiben (fühle mich nach hinten, aber oh well) - so bin ich hier veröffentlichen - wahrscheinlich für die Punkte verlieren ...

Da mein Punkt ist, die Aufmerksamkeit auf pzrq Antwort zu ziehen, bitte Glasur nicht über und verpassen es in allen unten. die ersten Zeilen dieses Beitrags sind die wichtigsten sind.

Meine Geschichte:

Das Problem, das ich hier kam war, wenn Sie wollen eine Ausnahme von einer Klasse fangen, die Sie keine Kontrolle haben - was dann ??? Ich werde sicherlich nicht alle möglichen Klassen meines Code in einem Versuch verwendet, um eine Unterklasse der Lage sein, eine Nachricht aus allen möglichen Ausnahmen zu erhalten!

Ich war mit:

except Exception as e:
   print '%s (%s)' % (e.message,type(e))

, die, wie wir alle wissen, die Warnung OP gibt gefragt (was mich hierher gebracht hat), und das, was pzrq als eine Möglichkeit gibt, es zu tun:

except Exception as e:
   print '%s (%s)' % (str(e),type(e))

nicht.

Ich bin nicht in einer Unicode-Umgebung, aber JJC Antwort machte mich fragen, so hatte ich es zu versuchen. In diesem Zusammenhang wird daraus:

except Exception as e:
   print '%s (%s)' % (unicode(e),type(e))

, die zu meiner Überraschung, arbeiteten genau wie str (e) -. So nun das ist, was ich mit

Sie wissen nicht, wenn ‚str (e) / Unicode (e)‘, der ‚genehmigt Python Weg‘ ist, und ich werde wahrscheinlich herausfinden, warum das nicht gut ist, wenn ich auf 3,0 zu bekommen, aber man hofft, dass die Fähigkeit, eine unerwartete Ausnahme (*), ohne zu sterben und noch einige Informationen daraus zu behandeln bekommt immer nicht weg ...

(*) Hmm. „Unerwartete Ausnahme“ - Ich glaube, ich stotterte nur

!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top