Sehen Sie sich die in Python 3.8.2 integrierte Ausnahmebaumstruktur an

Es ist eine Fortsetzung des folgenden Artikels

Sehen Sie sich die Baumstruktur der in Python integrierten Ausnahmen an

Zu verwendendes Skript, Umgebung, Verwendungsbeispiel

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)

Es ist im Wesentlichen dasselbe wie beim letzten Mal, aber wir haben alle alten Python 3-Schutzfunktionen und Python 2 aus der Unterstützung entfernt. Außerdem habe ich in letzter Zeit doppelte Anführungszeichen verwendet, weil Schwarz dies tut.

Verwenden Sie 3.7.7 als Vergleichsziel. Im vorherigen Artikel war der letzte "3.7.1", aber es gab keinen Unterschied im Ausnahmebaum, also habe ich ihn weggelassen.

Die vorliegende Umgebung ist MacOS 10.15.4, aber es sollte keinen Unterschied in der Python-Ebene geben.

Die Ausführungsmethode ist ungefähr wie folgt

$ 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
(Der gleiche Inhalt wie oben wird im Text gespeichert)

Ausführungsergebnis in 3.7.7 (Volltext)

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

Da dies eine Vergleichsquelle ist, werde ich nicht besonders darauf eingehen. Es schien keinen Unterschied in den Ergebnissen von 3.7.1 zu geben.

Ausführungsergebnis in 3.8.2 (Vergleich)

$ 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

Es ist ganz anders. Es ist das gleiche wie beim letzten Mal mit 3.8-dev und ich mache mir Sorgen, dass es einseitig "abnimmt", aber ich denke, das liegt an der Implementierung dieses Skripts.

Ich habe es bemerkt, als ich mir Was ist neu angeschaut habe, aber ich konnte überhaupt nicht alle Ausnahmen erfassen, dieses Skript. Kein gutes Kind!

asyncio.CancelledError

Dies ist nicht in erster Linie das Ergebnis.

Ich pflege nur einen schlampigen Artikel, damit ich nicht tiefer grabe, aber du solltest nicht denken, dass er erschöpfend ist, Maru.

Aber ich frage mich, warum ich es nicht fangen konnte. Wenn Sie es wissen (Nein, ich kann ein wenig raten)

Wie ich immer gefühlt habe, denke ich, dass es besser ist, diesen Ausnahmebaumzweig unter der Annahme herauszufordern, dass er sich als persönliches Gefühl ändern wird.

Zunächst sollten Sie als Entwicklungs-Know-how als Grundregel Ihre eigene Ausnahme von "Ausnahme" ableiten und sicherstellen, dass Ausnahmen, die explizit von Ihrem Code ausgegeben werden, durch "Ausnahme" klar von Laufzeitausnahmen getrennt sind. Halte es unten. Wenn Sie beispielsweise die Ausnahmeklassen mit einer feineren Körnung als "OSError" betrachten müssen, ist dies wie das Schreiben eines Komponententests, bei dem die Möglichkeit erkannt wird, dass er sich von Version zu Version ändert. Wenn Sie einen Test schreiben, der Ausnahmen im Komponententest abfängt, bemerkt der Komponententest dies sofort, auch wenn sich die Baumstruktur der Ausnahme ändert, wenn Sie die Laufzeit ändern, sodass Sie sich sicherer fühlen.

Ich habe nachgeforscht, während ich gesagt habe

Erstens unter der Voraussetzung, dass die Theorie der OOP lautet, dass Eltern nicht von Anfang an alle Kinderklassen haben sollten.

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.

Dies ist ein grundlegender Fehler, den ich gemacht habe. Ich habe es seit Jahren nicht mehr bemerkt (^^;

Schreiben wir das Skript wie folgt um

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)

Nehmen Sie einen Diff

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

Keine Änderung.

Es scheint also richtig zu sein, dass 3.8.2 die Anzahl der Ausnahmen nicht mindestens verringert hat und dass sie zu Beginn der Laufzeit nicht unnötig importiert wurden.

Wenn Sie explizit importieren, werden diese Ausnahmen natürlich zur Laufzeit geladen und befinden sich jetzt in der übergeordneten Klasse __subclasses__ ().

Dies ist eine einfache Verbesserung.

Recommended Posts

Sehen Sie sich die in Python 3.8.2 integrierte Ausnahmebaumstruktur an
Sehen Sie sich die in Python integrierte Ausnahmebaumstruktur an
Machen Sie einen Screenshot in Python
Werfen wir einen Blick auf den Scapy-Code. Wie bearbeiten Sie die Struktur?
Schauen Sie sich die Django-Vorlage an.
Werfen wir einen Blick auf die Feature-Map von YOLO v3
Ausgabebaumstruktur von Dateien in Python
Führen Sie den Python-Interpreter im Skript aus
Zeichnen Sie mit graphviz eine Baumstruktur in Python 3
[Python] Holen Sie sich die Dateien mit Python in den Ordner
Holen Sie sich den Aufrufer einer Funktion in Python
Kopieren Sie die Liste in Python
Ausgabe in Form eines Python-Arrays
[Python] Finden Sie die Translokationsmatrix in Einschlussnotation
Drehen Sie in Python mehrere Listen mit for-Anweisung gleichzeitig
Systemhandel beginnend mit Python3: Bio-Health-Aktien in der neuen Corona
Überprüfen Sie, ob die Zeichenfolge eine Zahl in Python ist
[Python] Machen Sie einen Screenshot
Werfen Sie einen Blick auf die Verarbeitung von LightGBM Tuner
Zeichnen einer Baumstruktur mit D3.js in Jupyter Notebook
C sprachähnliche Struktur in Python
Schreiben Sie in Python ein logarithmisches Histogramm auf die x-Achse
Ein Memorandum über die Umsetzung von Empfehlungen in Python
Sehen Sie sich das Profiling und Dumping mit Dataflow an
Nehmen Sie eine Instanz einer Python-Ausnahmeklasse nicht direkt als Argument für die Ausnahmeklasse!
Was bedeutet das letzte () in einer Funktion in Python?
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 2 heraus ~ Schauen wir uns die Eingabedaten genauer an ~
Finden Sie die scheinbare Breite einer Zeichenfolge in Python heraus
Versuchen Sie es mit dem Python-Webframework Django (2). Schauen Sie sich settings.py an
Erstellen Sie einen lokalen Bereich in Python, ohne den Namespace zu verschmutzen
Verwendung der Methode __call__ in der Python-Klasse
Ändern Sie das Standardausgabeziel in eine Datei in Python
Ein kurzer Blick auf Ihr Profil in der Django-App
Holen Sie sich die Anzahl der spezifischen Elemente in der Python-Liste
[Hinweis] Import von Dateien in das übergeordnete Verzeichnis in Python
So erhalten Sie den letzten (letzten) Wert in einer Liste in Python
So erhalten Sie eine Liste der integrierten Ausnahmen für Python
Erstellen Sie eine Funktion in Python
Erstellen Sie ein Wörterbuch in Python
Finde Fehler in Python
Erstellen Sie ein Lesezeichen in Python
Werfen wir einen Blick auf die Infektionstendenz des neuen Coronavirus COVID-19 in jedem Land und den Status der medizinischen Reaktion (zusätzliche Informationen).
Wenn Sie eine Programmiersprache lernen, sollten Sie sich zunächst das Familiendiagramm der Programmiersprache ansehen.
Spielen Sie Sounds in Python ab, vorausgesetzt, die Tastatur ist eine Klaviertastatur
So bestimmen Sie die Existenz eines Selenelements in Python
Wie Sie die interne Struktur eines Objekts in Python kennen
So überprüfen Sie die Speichergröße einer Variablen in Python
Löschen Sie ein bestimmtes Zeichen in Python, wenn es das letzte ist
Lesen Sie die Standardausgabe eines Unterprozesses zeilenweise in Python
Eine Funktion, die die Verarbeitungszeit einer Methode in Python misst
Ich habe mir genauer angesehen, warum Python selbst benötigt wird
Lesen Sie die Datei in Python mit einem relativen Pfad aus dem Programm
Rufen Sie die Formel in der Excel-Datei als Zeichenfolge in Python ab
Lösen Sie Teilsummenprobleme mit der vollständigen Suche in Python
Holen Sie sich die Anzahl der Leser von Artikeln über Mendeley in Python
Schauen wir uns den Waldbrand an der Westküste der USA mit Satellitenbildern an.