Les exceptions avec Python 3

Comment gérer les exceptions et créer les siennes

a marqué ce sujet comme résolu.
Auteur du sujet

Tout le monde se secoue ! :D

J’ai commencé (il y a 3 heures) la rédaction d’un tutoriel au doux nom de « Les exceptions avec Python 3 » et j’ai pour objectif de proposer en validation un texte aux petits oignons. Je fais donc appel à votre bonté sans limites pour dénicher le moindre pépin, que ce soit à propos du fond ou de la forme. Vous pourrez consulter la bêta à votre guise à l’adresse suivante :

A priori, le contenu est à peu près terminé. Je voulais faire quelque chose qui se lise rapidement et qui ne s’écarte pas trop du sujet. Cependant, j’ai l’impression que le contenu devrait être plus "aéré", qu’en pensez-vous ? Dois-je enlever quelques exemples de code ?

TODO :

  • Introduction
  • Conclusion
  • Logo
  • Ortho/typo

Merci !

Édité par rezemika

"Les accidents dans un système doivent se produire, mais il n’est pas obligatoire qu’ils produisent pour vous et moi." Laurence Gonzales - Deep Survival

+0 -0

Salut,

En effet, sans introduction le début de la lecture est pour le moment un peu brut. Aussi, je suis gêné par la première phrase, qui occulte que des levées d’exceptions peuvent être des situations tout à fait normales, et n’empêchent en rien le programme de continuer son exécution, l’exemple le plus flagrant étant StopIteration.

En parlant d’exemple, le premier que tu donnes n’est pas terrible puisque l’erreur de syntaxe qui survient n’est pas une exception (bien que SyntaxError soit une classe d’exception, ce n’est pas la même chose). Tu ne peux pas l’attraper par exemple.

Il y a quelques confusions dans le vocabulaire, comme quand tu parles de TypeError levée par une fonction et que l’exemple présente une addition, ou entre itérable et indexable même si le paragraphe se comprend globalement bien, ou encore dire qu’une classe « contiendrait » pass (c’est plus le bloc de définition qui contient le mot-clé).

Tous les codes présentés dans la première section sont dans l’interpréteur interactif, et tu expliques que les exceptions sont accessibles depuis le terminal. C’est bien, mais lever une exception se fait très rarement dans ce cas d’usage, donc ça fait un peu bizarre.

Je ne comprends pas trop le paragraphe sur les chaînes de formatage et sur le fait de modifier la chaîne.

Les exemples donnés gagneraient sûrement à refléter des problèmes de la vie réelle, plutôt que des cas d’école qui ne correspondent pas à grand chose.

Tu conseilles de ne pas abuser d’exceptions personnalisée par rapport à la réutilisation du code, mais justement, dans la réalisation d’une bibliothèque par exemple il est souvent bien plus facile d’avoir des exceptions qui héritent toutes d’une base commune pour pouvoir les filtrer plus ou moins finement, comme expliqué ici.

Au passage, toutes les exceptions n’héritent pas de la classe Exception, je t’invite à lire la page dont je donne le lien plus bas.

Je ne comprends pas ce que tu veux dire par «  il faut penser à ajouter un paramètre dédié et à appeler la méthode __init__ de Exception avec ce paramètre » ni à quel moment dans le code tu fais appel à la méthode de la classe parente.

Aussi, cela manque de liens vers des sources complémentaires, comme la hiérarchie des classes d’exception Python.

Édité par entwanne

J’ai pas eu le temps de tout lire, néanmoins bien que les exceptions soient très pratiques je sais que niveau complexité/temps c’est vraiment affreux, je ne sais plus où j’avais lu ça mais je crois que par exemple en Java c’est vraiment pas opti. Dans d’autres langages comme OCaml apparement c’est justement beaucoup mieux mis en place, et donc les exceptions ne sont pas trop gourmandes (je ne sais pas par contre pourquoi techniquement c’est plus rapide en OCaml).

Je profite donc du thread pour demander si en Python les exceptions bien que très importantes sont gourmandes niveau temps ou pas ?

(Voilà j’espère que le thread est adapté et que je ne suis pas hors-sujet auquel cas je m’excuse).

+0 -0

Coucou, \o

J’ai rien à ajouter aux remarques de entwanne (si ce n’est qu’une conclusion, ce serait bien). Le tutoriel est cool.

Si ! Les mot-clés ne ressorte pas forcément super bien. Ce n’est que mon avis cependant. Facile à améliorer, ça doit valoir le coup.

ache.one                 🦹         👾                                🦊

+0 -0

Je profite donc du thread pour demander si en Python les exceptions bien que très importantes sont gourmandes niveau temps ou pas ?

À l’échelle de Python, le mécanisme n’a pas vraiment de grosse incidence sur le temps d’exécution d’un programme.

I was a llama before it was cool

+1 -0

Salut,

Le lien de bas de page pour lark n’est pas correct.

Je fais un carnage si ce car nage car je nage, moi, Karnaj ! - Le comble pour un professeur de mathématique ? Mourir dans l’exercice de ses fonctions.

+0 -0

Je profite donc du thread pour demander si en Python les exceptions bien que très importantes sont gourmandes niveau temps ou pas ?

À l’échelle de Python, le mécanisme n’a pas vraiment de grosse incidence sur le temps d’exécution d’un programme.

nohar

Et même, en python il y a l’adage "better ask forgiveness than permission". Les erreurs sont très rapides en python et il peut être plus rapide d’en générer que de vérifier qu’on ne va pas en lever. Un ami avait amélioré les perfs du logiciel de sa boîte en passant par les exceptions, une fois.

+2 -0

Sinon pour en revenir au contenu du tuto, pour moi il manque encore des trucs que j’utilise tous les jours.

except ... as ...: : (Edit: ah si, il y est)

1
2
3
4
5
try:
   # ...
   pass
except ValueError as err: 
   print("Something went wrong:", err)

raise ... from ...:

1
2
3
4
5
6
7
8
9
class MyError(Exception):
   pass

try:
   # ...
   pass
except ValueError as err: 
   # indique que err est la cause directe de MyError
   raise MyError("Something went wrong") from err

et raise sans argument

1
2
3
4
5
6
try:
    # ...
    pass
except (ValueError, RuntimeError) as err:
    print("Something went wrong:", err)
    raise  # Relance l'exception sans affecter son traceback

Édité par nohar

I was a llama before it was cool

+1 -0
Auteur du sujet

Merci pour vos retours !

Aussi, je suis gêné par la première phrase, qui occulte que des levées d’exceptions peuvent être des situations tout à fait normales, et n’empêchent en rien le programme de continuer son exécution, l’exemple le plus flagrant étant StopIteration.

En effet, mais du coup je ne vois pas trop comment formuler ça. C’est la première fois que je rédige un contenu sur le Python, peut-être ai-je un peu dépassé ma "limite pédagogique".

Il y a quelques confusions dans le vocabulaire, comme quand tu parles de TypeError levée par une fonction et que l’exemple présente une addition

N’est-ce pas la fonction (enfin la méthode) __add__ du type int qui lève cette exception (bien que ça puisse être confus, je vais modifier ça) ?

C’est bien, mais lever une exception se fait très rarement dans ce cas d’usage, donc ça fait un peu bizarre.

En effet, je voulais simplement qu’il n’y a pas besoin d’importer quelque chose pour lever une exception (elles sont dans les builtins). Et vu que le terminal permet d’essayer des petits bouts de code facilement, je me suis dit que ça en faisait un bon outil pour débuter.

Les exemples donnés gagneraient sûrement à refléter des problèmes de la vie réelle, plutôt que des cas d’école qui ne correspondent pas à grand chose.

Je vais être limité par mon expérience. À part dans des "gros" morceaux de code, je ne les utilise qu’occasionnellement.

Tu conseilles de ne pas abuser d’exceptions personnalisée par rapport à la réutilisation du code, mais justement, dans la réalisation d’une bibliothèque par exemple il est souvent bien plus facile d’avoir des exceptions qui héritent toutes d’une base commune pour pouvoir les filtrer plus ou moins finement, comme expliqué ici.

En effet, mais là je pensais plutôt aux exceptions comme TypeError. Si on créé un module qui fourni une fonction qui prend un int en paramètre et qu’on lui passe une str, il vaut mieux (à mon humble avis) lever une TypeError qu’une exception perso. En revanche, si le traitement du nombre passé en paramètre produit une erreur, alors en effet, une exception qui hérite d’une autre dédiée au module est plus adaptée.

Je ne comprends pas ce que tu veux dire par «  il faut penser à ajouter un paramètre dédié et à appeler la méthode init de Exception avec ce paramètre » ni à quel moment dans le code tu fais appel à la méthode de la classe parente.

En effet, petit oubli de ma part. Je corrige.


Bien vu nohar, je vais les rajouter.


J’ai été très pris ces derniers temps et je n’ai donc pas programmé depuis longtemps. Me lancer dans un mini-tuto sur le sujet était peut-être un peu présomptueux de ma part. Du coup, n’hésitez surtout pas à reprendre ce tuto si vous voulez faire quelque chose de votre côté ! ;)

Édité par rezemika

"Les accidents dans un système doivent se produire, mais il n’est pas obligatoire qu’ils produisent pour vous et moi." Laurence Gonzales - Deep Survival

+0 -0
Auteur du sujet

Bonjour les agrumes !

La bêta a été mise à jour et décante sa pulpe à l’adresse suivante :

Merci d’avance pour vos commentaires.

"Les accidents dans un système doivent se produire, mais il n’est pas obligatoire qu’ils produisent pour vous et moi." Laurence Gonzales - Deep Survival

+0 -0

En effet, mais du coup je ne vois pas trop comment formuler ça. C’est la première fois que je rédige un contenu sur le Python, peut-être ai-je un peu dépassé ma "limite pédagogique".

rezemika

Pour moi le plus simple serait de renverser la proposition, de dire qu’un cas anormal est signalé par une exception.

N’est-ce pas la fonction (enfin la méthode) __add__ du type int qui lève cette exception (bien que ça puisse être confus, je vais modifier ça) ?

rezemika

Techniquement c’est bien ce qu’il se passe, si, mais c’est implicite est ça ne transparaît pas quand on voit l’expression. Dire « opération » ou « expression » serait plus générique.

En effet, je voulais simplement qu’il n’y a pas besoin d’importer quelque chose pour lever une exception (elles sont dans les builtins). Et vu que le terminal permet d’essayer des petits bouts de code facilement, je me suis dit que ça en faisait un bon outil pour débuter.

rezemika

Je vois ce que tu veux dire mais je pense que tu gagnerais à présenter tes exemples les plus complexes comme des fichiers.

Je vais être limité par mon expérience. À part dans des "gros" morceaux de code, je ne les utilise qu’occasionnellement.

rezemika

Il y a pas mal de choses qui peuvent être faites avec IndexError ou KeyError, dans la manipulation de structures de données.

En effet, mais là je pensais plutôt aux exceptions comme TypeError. Si on créé un module qui fourni une fonction qui prend un int en paramètre et qu’on lui passe une str, il vaut mieux (à mon humble avis) lever une TypeError qu’une exception perso. En revanche, si le traitement du nombre passé en paramètre produit une erreur, alors en effet, une exception qui hérite d’une autre dédiée au module est plus adaptée.

rezemika

Combiner les deux n’est pas impossible. Je n’ai pas de cas précis en tête, mais on pourrait imaginer une exception héritant à la fois de MyLibError et ValueError. Pour TypeError c’est un peu plus tordu en effet.

J’ai été très pris ces derniers temps et je n’ai donc pas programmé depuis longtemps. Me lancer dans un mini-tuto sur le sujet était peut-être un peu présomptueux de ma part. Du coup, n’hésitez surtout pas à reprendre ce tuto si vous voulez faire quelque chose de votre côté ! ;)

rezemika

Présomptueux je ne pense pas, non, c’est globalement du bon travail pour un premier jet. Après on trouvera toujours quelques petites choses à redire. :p

Je n’ai pas trop le temps de relire la nouvelle version là, mais j’y jetterai un œil plus tard.

Auteur du sujet

Bonjour les agrumes !

La bêta a été mise à jour et décante sa pulpe à l’adresse suivante :

Voici une seconde mise à jour ! J’ai ajouté une intro, enlevé les chevrons du terminal sur les gros exemples et corrigés quelques détails. Il me reste encore à rendre les exemples plus concrets.

Merci d’avance pour vos commentaires.

Édité par rezemika

"Les accidents dans un système doivent se produire, mais il n’est pas obligatoire qu’ils produisent pour vous et moi." Laurence Gonzales - Deep Survival

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte