Vor kurzem habe ich mich gefragt, wie ich die Anzeige von Modulausnahmen in Python verständlicher machen kann, aber ich habe die beste Methode gefunden und sie zusammengefasst. Lassen Sie uns zunächst die allgemeine Methode zum Definieren von Modulausnahmen überprüfen.
Betrachten wir als konkrete Situation die Situation beim Schreiben des urllib83-Moduls, das aus der Funktion urllib83.urlopen ()
in Python 3.3 besteht.
urllib83 bedeutet das 83. urllib-Modul, aber es tut mir leid, wenn in Zukunft ein Standardmodul mit demselben Namen angezeigt wird.
Nehmen wir außerdem an, dass dieses Modul aus den folgenden drei Dateien besteht.
urllib83/__init__.py
ftp.py
http.py
Wenn Sie mit aller Kraft "urllib83.urlopen ()" schreiben, sollte es so aussehen.
__init__.py
from .ftp import ftpopen
from .http import httpopen
def urlopen(url):
if url.startswith("ftp://"):
return ftpopen(url)
else:
return httpopen(url)
Als nächstes nehmen wir an, dass dieses Modul die Ausnahmeklassen "urllib83.FTPError" und "urllib83.HTTPError" hat, die beide von der Basisausnahmeklasse "urllib83.Urllib83Error" erben. Wenn Sie diese drei Ausnahmeklassen gehorsam implementieren, wird in `urllib83 / __ init __. Py '
urllib83/__init__.py
class Urllib83Error(Exception):
pass
class FTPError(Urllib83Error):
pass
class HTTPError(Urllib83Error):
pass
Ich denke, dass es definiert wird als, aber es gibt ein Problem mit dieser Methode.
urllib83.FTPError
wird natürlich in urllib83 / ftp.py
ausgelöst, also wird ftp.py`` FTPError
auslösen,
urllib83/ftp.py
from . import FTPError
def ftpopen(url):
...
raise FTPError
Es wird beim Importieren von like verwendet, aber wie oben erwähnt, importiert __init __. Py`` ftpopen ()
from ftp.py
.
Bei dieser Rate importieren sich "__init __. Py" und "ftp.py" gegenseitig, was das Problem des zirkulären Imports verursacht.
Um dieses Problem zu vermeiden, fügen Sie im Allgemeinen eine Datei mit dem Namen "urllib83 / Errors.py" hinzu und erstellen Sie sie wie folgt.
urllib83/errors.py
class Urllib83Error(Exception):
pass
class FTPError(Urllib83Error):
pass
class HTTPError(Urllib83Error):
pass
Jede andere Datei als error.py
__init__.py
from .errors import Urllib83Error, FTPError, HTTPError
__all__ = ['Urllib83Error', 'FTPError', 'HTTPError']
Importieren Sie die erforderliche Ausnahmeklasse wie in. (Hinweis:__all__
Benötigt die Leitung__init__.py
nur. )
__init__.py
Importiert auch die Ausnahmeklasse, also auch die Seite, die das urllib83-Modul verwendet
client.py
from urllib83 import urlopen, Urllib83Error
try:
urlopen(url)
except Urllib83Error:
pass
Sie können solche Modulausnahmen verwenden. Daran ist nichts auszusetzen.
##Was ist los?##
Was mich interessierte war, dass die Seite, die das urllib83-Modul verwendet, es versuchte...Ohne die Ausnahme-Anweisung zu verwendenurllib83.urlopen()
Wenn du anrufst.
urllib83.FTPError
Wenn dies auftritt, wird der Traceback wie unten gezeigt angezeigt.
python
>>> import urllib83
>>> urllib83.urlopen("ftp://")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "./urllib83/__init__.py", line 10, in urlopen
return ftpopen(url)
File "./urllib83/ftp.py", line 4, in ftpopen
raise FTPError
urllib83.errors.FTPError
>>>
In der letzten Zeileurllib83.FTPError
nicht,urllib83.errors.FTPError
Wird angezeigt.
Das ist ein Problem,urllib83.FTPError
Ich bin der Meinung, dass es angezeigt werden sollte.
Die allgemeine Ansicht der Pythonista-Leute lautet jedoch: "Ich habe keine Ahnung, wo das Problem in dieser Anzeige liegt." Der Grund ist
Die Dokumentation zum Modul urllib83
urllib83.FTPError
Wird auftreten, und der Benutzer wird in der Ausnahmeklausel sagen,except urllib83.FTPError:
Sie können die aufgetretene Ausnahme schriftlich ergänzen. Das Problem besteht nirgendwo, da es gemäß den in der Dokumentation beschriebenen Spezifikationen funktioniert
ist das, was sie sagten. Andererseits ist mein Gegenargument dazu
Benutzer des urllib83-Moduls
urllib83.errors.FTPError
Wurde in der Dokumentation des urllib83-Moduls erwähnt, als ich tatsächlich auf die Indikation stießurllib83.FTPError
Ist es nicht zu teuer, das zu wissen? Von Anfang an,urllib83.FTPError
Ist einfacher zu verstehen und benutzerfreundlich, daher sollten Sie etwas dagegen tun.
Das ist.
##Lösungen##
urllib83.FTPError
Ich habe verschiedene Möglichkeiten ausprobiert, um es anzuzeigen, aber am Endeerrors.py
Ausnahmeklasse mit
errors.py
_SAVED_NAME = __name__
__name__ = __package__
# __name__ = "urllib83" # Klicken Sie hier für Python 3.2
class Urllib83Error(Exception):
pass
class FTPError(Urllib83Error):
pass
class HTTPError(Urllib83Error):
pass
__name__ = _SAVED_NAME
Ich bin zu dem Schluss gekommen, dass es am besten ist, es als zu definieren.
Der Punkt ist__name__
Schreiben Sie den Inhalt des Attributs vorübergehend neu und stellen Sie ihn wieder her, wenn die Ausnahmeklasse definiert wurde.
Wenn eine Ausnahme auftritt, wird Folgendes angezeigt.
python
>>> import urllib83
>>> urllib83.urlopen("ftp://")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "./urllib83/__init__.py", line 10, in urlopen
return ftpopen(url)
File "./urllib83/ftp.py", line 4, in ftpopen
raise FTPError
urllib83.FTPError
>>>
Richtigurllib83.FTPError
Wird angezeigt.
__name__
Das Umschreiben von Attributen ist nicht üblich. Wenn Sie komplexen Code schreiben,urllib83/__init__.py
Es kann einen Unterschied zu der Definition in geben__name__
Wir empfehlen dringend, dass Sie beim Umschreiben von Attributen eine komplizierte Verarbeitung so weit wie möglich vermeiden.
dann,__name__
Vergessen Sie nicht, die Attribute rückgängig zu machen.
##Schließlich## Bisher haben wir keine Probleme mit dieser Methode gefunden. Wenn Sie jedoch Probleme bemerken, teilen Sie uns dies bitte in den Kommentaren mit. Stimmt etwas mit der integrierten Entwicklungsumgebung nicht? Darüber mache ich mir besonders Sorgen.
Recommended Posts