Jetez un œil à l'arborescence des exceptions intégrée dans Python 3.8.2

C'est une position de continuation de l'article suivant

Regardez l'arborescence des exceptions intégrées dans Python

Script à utiliser, environnement, exemple d'utilisation

class_tree.py


#!/usr/bin/env python

import platform


def show_class_tree(cls, depth=0):
    prefix = "" if depth == 0 else "." * (depth * 3) + " "
    if cls.__name__.lower() == "error":
        print("{}{} ({})".format(prefix, cls.__name__, cls))
    else:
        print("{}{}".format(prefix, cls.__name__))
    for subcls in sorted(cls.__subclasses__(), key=lambda c: c.__name__):
        show_class_tree(subcls, depth+1)


if __name__ == "__main__":
    print("Python Version: {}".format(platform.python_version()))
    print()
    show_class_tree(BaseException)

C'est essentiellement la même chose que la dernière fois, mais nous avons supprimé toutes les anciennes protections Python 3 et Python 2 du support. De plus, j'ai utilisé des guillemets doubles récemment parce que le noir le fait.

Utilisez «3.7.7» comme cible de comparaison. Dans l'article précédent, le dernier était «3.7.1», mais il n'y avait aucune différence dans l'arborescence des exceptions, donc je l'ai omis.

L'environnement disponible est MacOS 10.15.4, mais il ne devrait y avoir aucune différence dans la couche Python.

La méthode d'exécution est à peu près la suivante

$ python -V
Python 3.7.7
$ python class_tree.py | tee $(python -c 'import platform; print("".join(platform.python_version_tuple()) + ".txt")')
Python Version: 3.7.7

...

$ cat 377.txt
(Le même contenu que ci-dessus est enregistré dans le texte)

Résultat d'exécution en 3.7.7 (texte intégral)

Python Version: 3.7.7

BaseException
... Exception
...... ArithmeticError
......... FloatingPointError
......... OverflowError
......... ZeroDivisionError
...... AssertionError
...... AttributeError
...... BufferError
...... EOFError
...... Error (<class 'locale.Error'>)
...... ImportError
......... ModuleNotFoundError
......... ZipImportError
...... LookupError
......... CodecRegistryError
......... IndexError
......... KeyError
...... MemoryError
...... NameError
......... UnboundLocalError
...... OSError
......... BlockingIOError
......... ChildProcessError
......... ConnectionError
............ BrokenPipeError
............ ConnectionAbortedError
............ ConnectionRefusedError
............ ConnectionResetError
......... FileExistsError
......... FileNotFoundError
......... InterruptedError
......... IsADirectoryError
......... ItimerError
......... NotADirectoryError
......... PermissionError
......... ProcessLookupError
......... TimeoutError
......... UnsupportedOperation
...... ReferenceError
...... RuntimeError
......... BrokenBarrierError
......... NotImplementedError
......... RecursionError
......... _DeadlockError
...... StopAsyncIteration
...... StopIteration
...... StopTokenizing
...... SubprocessError
......... CalledProcessError
......... TimeoutExpired
...... SyntaxError
......... IndentationError
............ TabError
...... SystemError
......... CodecRegistryError
...... TokenError
...... TypeError
...... ValueError
......... UnicodeError
............ UnicodeDecodeError
............ UnicodeEncodeError
............ UnicodeTranslateError
......... UnsupportedOperation
...... Verbose
...... Warning
......... BytesWarning
......... DeprecationWarning
......... FutureWarning
......... ImportWarning
......... PendingDeprecationWarning
......... ResourceWarning
......... RuntimeWarning
......... SyntaxWarning
......... UnicodeWarning
......... UserWarning
...... _OptionError
...... error (<class 're.error'>)
... GeneratorExit
... KeyboardInterrupt
... SystemExit

Puisqu'il s'agit d'une source de comparaison, je ne ferai pas de commentaire en particulier. Il ne semblait y avoir aucune différence dans les résultats de 3.7.1.

Résultat d'exécution en 3.8.2 (comparaison)

$ diff 377.txt 382.txt
1c1
< Python Version: 3.7.7
---
> Python Version: 3.8.2
44d43
< ......... BrokenBarrierError
50,53d48
< ...... StopTokenizing
< ...... SubprocessError
< ......... CalledProcessError
< ......... TimeoutExpired
59d53
< ...... TokenError
79d72
< ...... _OptionError

C'est assez différent. C'est la même chose que la version 3.8-dev la dernière fois, et je crains qu'elle ne "diminue" unilatéralement, mais je pense que cela est dû à l'implémentation de ce script.

J'ai remarqué quand j'ai regardé Quoi de neuf, mais je n'ai pas pu saisir toutes les exceptions en premier lieu, ce script. Pas de bon enfant!

asyncio.CancelledError

Ce n'est pas le résultat en premier lieu.

Je ne fais que maintenir un article bâclé, donc je ne vais pas creuser plus profondément, mais vous ne devriez pas penser que c'est exhaustif, Maru.

Mais je me demande pourquoi je n'ai pas pu l'attraper. Si tu le sais (non, je peux le prédire un peu)

Comme je l'ai toujours ressenti, je pense qu'il vaut mieux contester cette branche d'arbre d'exception en supposant qu'elle changera en tant que sentiment personnel.

Tout d'abord, en tant que savoir-faire de développement, c'est fondamentalement un endroit où vous dérivez votre propre exception de ʻException et assurez-vous que l'exception que votre code émet explicitement est clairement séparée de l'exception d'exécution par ʻexcept. Taisez-vous. Si vous avez besoin, par exemple, de regarder les classes d'exceptions avec un grain plus fin que ʻOSError`, c'est comme écrire un test unitaire, en reconnaissant la possibilité qu'il change d'une version à l'autre. Si vous écrivez un test qui détecte les exceptions dans le test unitaire, même si l'arborescence de l'exception change lorsque vous modifiez le runtime, le test unitaire le remarquera immédiatement, vous vous sentirez donc plus en sécurité.

J'ai enquêté en disant

En premier lieu, en partant du principe que la théorie de la POO est que les parents ne devraient pas avoir toutes les classes pour enfants dès le début.

https://stackoverflow.com/questions/3862310/how-to-find-all-the-subclasses-of-a-class-given-its-name

Note that if the class definition of a subclass hasn't been executed yet - for example, if the subclass's module hasn't been imported yet - then that subclass doesn't exist yet, and subclasses won't find it.

C'est une erreur fondamentale que j'ai faite. Je n'ai pas remarqué depuis des années (^^;

Réécrivons le script comme suit

class_tree_mod.py


#!/usr/bin/env python

import platform

from threading import BrokenBarrierError
from tokenize import StopTokenizing
from warnings import _OptionError
from subprocess import SubprocessError


def show_class_tree(cls, depth=0):
    prefix = "" if depth == 0 else "." * (depth * 3) + " "
    if cls.__name__.lower() == "error":
        print("{}{} ({})".format(prefix, cls.__name__, cls))
    else:
        print("{}{}".format(prefix, cls.__name__))
    for subcls in sorted(cls.__subclasses__(), key=lambda c: c.__name__):
        show_class_tree(subcls, depth+1)


if __name__ == "__main__":
    print("Python Version: {}".format(platform.python_version()))
    print()
    show_class_tree(BaseException)

Prenez un diff

$ diff 377.txt 382.txt
1c1
< Python Version: 3.7.7
---
> Python Version: 3.8.2

Pas de changement.

Il semble donc exact que 3.8.2 n'a pas au moins réduit le nombre d'exceptions, et qu'elles n'ont pas été importées inutilement au démarrage du runtime.

Bien sûr, lorsque vous importez explicitement, ces exceptions sont chargées au moment de l'exécution et peuvent maintenant être trouvées dans la classe parente __subclasses__ ().

C'est une simple amélioration.

Recommended Posts

Jetez un œil à l'arborescence des exceptions intégrée dans Python 3.8.2
Jetez un œil à l'arborescence des exceptions intégrée à Python
Prendre une capture d'écran en Python
Jetons un coup d'œil au code Scapy. Comment traitez-vous la structure?
Jetez un œil au modèle Django.
Jetons un coup d'œil à la carte des fonctionnalités de YOLO v3
Arborescence de sortie des fichiers en Python
Exécuter l'interpréteur Python dans le script
Dessinez une structure arborescente en Python 3 à l'aide de graphviz
[Python] Récupérez les fichiers dans le dossier avec Python
Récupérer l'appelant d'une fonction en Python
Copiez la liste en Python
Sortie sous la forme d'un tableau python
[Python] Trouvez la matrice de translocation en notation d'inclusion
Transformez plusieurs listes avec l'instruction for en même temps en Python
Commerce de système à partir de Python3: les stocks de bio-santé à examiner dans le nouveau Corona
Vérifiez si la chaîne est un nombre en python
[Python] Prenez une capture d'écran
Jetez un œil au traitement de LightGBM Tuner
Dessiner une structure arborescente avec D3.js dans Jupyter Notebook
Structure de type langage C en Python
Ecrire un histogramme à l'échelle logarithmique sur l'axe des x en python
Un mémorandum sur la mise en œuvre des recommandations en Python
Jetez un œil au profilage et au vidage avec Dataflow
Ne prenez pas une instance d'une classe d'exception Python directement comme argument de la classe d'exception!
Que signifie le dernier () dans une fonction en Python?
Challenge classification des images par TensorFlow2 + Keras 2 ~ Regardons de plus près les données d'entrée ~
Découvrez la largeur apparente d'une chaîne en python
Essayez d'utiliser le framework Web Python Django (2) - Regardez setting.py
Créer une portée locale en Python sans polluer l'espace de noms
Comment utiliser la méthode __call__ dans la classe Python
Changer la destination de sortie standard en un fichier en Python
Un aperçu rapide de votre profil dans l'appli django
Obtenez le nombre d'éléments spécifiques dans la liste python
[Note] Importation de fichiers dans le répertoire parent en Python
Comment obtenir la dernière (dernière) valeur d'une liste en Python
Comment obtenir une liste d'exceptions intégrées pour python
Créer une fonction en Python
Créer un dictionnaire en Python
Trouver des erreurs en Python
Créer un bookmarklet en Python
Jetons un coup d'œil à la tendance infectieuse du nouveau coronavirus COVID-19 dans chaque pays et à l'état de la réponse médicale (informations supplémentaires).
Lors de l'apprentissage d'un langage de programmation, il est judicieux de regarder d'abord le diagramme de famille du langage de programmation.
Jouez des sons en Python en supposant que le clavier est un clavier de piano
Comment déterminer l'existence d'un élément sélénium en Python
Comment connaître la structure interne d'un objet en Python
Comment vérifier la taille de la mémoire d'une variable en Python
Supprimer un caractère spécifique en Python s'il s'agit du dernier
Lire la sortie standard d'un sous-processus ligne par ligne en Python
Une fonction qui mesure le temps de traitement d'une méthode en python
J'ai examiné de plus près pourquoi l'auto Python est nécessaire
Lisez le fichier en Python avec un chemin relatif depuis le programme
Obtenez la formule dans le fichier Excel sous forme de chaîne en Python
Résolvez les problèmes de somme partielle avec une recherche complète en Python
Obtenez le nombre de lecteurs d'articles sur Mendeley en Python
Jetons un coup d'œil à l'incendie de forêt sur la côte ouest des États-Unis avec des images satellites.