Je reçois un avertissement indiquant que BaseException.message est obsolète dans Python 2.6 lorsque j'utilise l'exception définie par l'utilisateur suivante:
class MyException(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
Voici l'avertissement:
DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message
Quel est le problème avec ça? Que dois-je changer pour me débarrasser de l'avertissement d'obsolescence?
python
exception
deprecated
désolé
la source
la source
Réponses:
Solution - presque aucun codage nécessaire
Héritez simplement votre classe d'exception
Exception
et passez le message comme premier paramètre au constructeurExemple:
Vous pouvez utiliser
str(my)
ou (moins élégant)my.args[0]
pour accéder au message personnalisé.Contexte
Dans les versions plus récentes de Python (à partir de 2.6), nous sommes censés hériter de nos classes d'exceptions personnalisées d'Exception qui (à partir de Python 2.5 ) héritent de BaseException. Le contexte est décrit en détail dans la PEP 352 .
__str__
et__repr__
sont déjà implémentés de manière significative, en particulier pour le cas d'un seul argument (qui peut être utilisé comme message).Vous n'avez pas besoin de répéter
__str__
ou de__init__
mettre en œuvre ou de créer_get_message
comme suggéré par d'autres.la source
str
breaks si l'exception a été construite avec un argument unicode:str(MyException(u'\xe5'))
raisesUnicodeEncodeError
. Utiliser à launicode
place destr
n'est pas infaillible non plus carunicode(MyException('\xe5'))
lève UnicodeDecodeError. Cela signifie-t-il que si je ne sais pas à l'avance si l'argument eststr
ouunicode
, je dois utiliser.args[0]
là où j'ai précédemment utilisé.message
?.message
dans notre projet par.args[0]
, et cela ne nous a posé aucun problème.Oui, il est obsolète dans Python 2.6 car il disparaît dans Python 3.0
La classe BaseException ne fournit plus un moyen de stocker le message d'erreur. Vous devrez le mettre en œuvre vous-même. Vous pouvez le faire avec une sous-classe qui utilise une propriété pour stocker le message.
J'espère que cela t'aides
la source
@property
syntaxe lorsque vous avez vraiment besoin d'encapsulation.@property
pour désactiver l'avertissement d' obsolescence .Ceci est votre classe dans le style Python2.6. La nouvelle exception prend un nombre arbitraire d'arguments.
la source
Comment reproduire l'avertissement
Permettez-moi de clarifier le problème, car on ne peut pas le répliquer avec l'exemple de code de la question, cela répliquera l'avertissement dans Python 2.6 et 2.7, si vous avez des avertissements activés (via l'
-W
indicateur , laPYTHONWARNINGS
variable d'environnement ou le module d'avertissement ):Arrête d'utiliser
.message
Je préfère
repr(error)
, qui retourne une chaîne qui contient le nom du type d'erreur, la repr du message, s'il y en a une, et la repr des arguments restants.Élimination de l'avertissement pendant l'utilisation
.message
Et la façon dont vous vous débarrasser de l'
DeprecationWarning
est de sous - classe une exception builtin que les concepteurs Python destinés:obtenir juste l'
.message
attribut sanserror.message
Si vous savez qu'il y avait un argument, un message, à l'exception et que c'est ce que vous voulez, il est préférable d'éviter l'attribut message et de prendre simplement le
str
de l'erreur. Dites pour un sous-classéException
:Et l'utilisation:
Voir aussi cette réponse:
Comment déclarer des exceptions personnalisées dans Python moderne?
la source
Pour autant que je sache, utiliser simplement un nom différent pour l'attribut message évite le conflit avec la classe de base et arrête ainsi l'avertissement de dépréciation:
Cela me semble être un hack.
Peut-être que quelqu'un peut expliquer pourquoi l'avertissement est émis même lorsque la sous-classe définit explicitement un attribut de message. Si la classe de base n'a plus cet attribut, il ne devrait pas y avoir de problème.
la source
Dans la continuité de la réponse de geekQ , le remplacement de code préféré dépend de ce que vous devez faire:
Parfois, les exceptions ont plus d'un argument, il
my.args[0]
n'est donc pas garanti de fournir toutes les informations pertinentes.Par exemple:
Imprime comme sortie:
Cependant, c'est un compromis sensible au contexte, car par exemple:
la source
str(my)
place demy.message
.Le conseil d'utiliser str (myexception) conduit à des problèmes Unicode en python 2.7, par exemple:
:(
fonctionne comme prévu et est préférable dans les cas où une partie du contenu de la chaîne d'erreur inclut une entrée utilisateur
la source
Le message de pzrq dit d'utiliser:
C'était exactement ce dont j'avais besoin.
(Si vous êtes dans un environnement Unicode, il semble que:
fonctionnera, et cela semble fonctionner correctement dans un environnement non-unicode)
Pzrq a dit beaucoup d'autres bonnes choses, mais j'ai failli manquer leur réponse à cause de toutes les bonnes choses. Comme je n'ai pas 50 points, je ne peux pas commenter leur réponse pour tenter d'attirer l'attention sur la solution simple qui fonctionne, et comme je n'en ai pas 15, je ne peux pas voter pour cette réponse, mais je peux poster (je me sens en arrière, mais eh bien) - alors ici je poste - probablement perdre des points pour ça ...
Étant donné que mon objectif est d'attirer l'attention sur la réponse de pzrq, veuillez ne pas le glacer et le manquer dans tout ce qui suit. les premières lignes de cet article sont les plus importantes.
Mon histoire:
Le problème pour lequel je suis venu ici était si vous vouliez attraper une exception d'une classe sur laquelle vous n'avez aucun contrôle - que faire alors ??? Je ne vais certainement pas sous-classer toutes les classes possibles que mon code utilise pour tenter d'obtenir un message de toutes les exceptions possibles!
J'utilisais:
qui, comme nous le savons tous maintenant, donne l'avertissement OP demandé (qui m'a amené ici), et ce, que pzrq donne comme moyen de le faire:
pas.
Je ne suis pas dans un environnement unicode, mais la réponse de jjc m'a fait me demander, alors j'ai dû l'essayer. Dans ce contexte, cela devient:
qui, à ma grande surprise, fonctionnait exactement comme str (e) - c'est donc ce que j'utilise.
Je ne sais pas si 'str (e) / unicode (e)' est la 'méthode Python approuvée', et je découvrirai probablement pourquoi ce n'est pas bon quand j'arrive à 3.0, mais on espère que la capacité de gérer un exception inattendue (*) sans mourir et obtenir encore des informations ne disparaîtra jamais ...
(*) Hmm. "exception inattendue" - je pense que je viens de bégayer!
la source