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__.pynur. )
__init__.pyImportiert 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.FTPErrorWenn 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.FTPErrornicht,urllib83.errors.FTPErrorWird angezeigt.
Das ist ein Problem,urllib83.FTPErrorIch 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.FTPErrorWird 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.FTPErrorWurde in der Dokumentation des urllib83-Moduls erwähnt, als ich tatsächlich auf die Indikation stießurllib83.FTPErrorIst es nicht zu teuer, das zu wissen? Von Anfang an,urllib83.FTPErrorIst einfacher zu verstehen und benutzerfreundlich, daher sollten Sie etwas dagegen tun.
Das ist.
##Lösungen##
urllib83.FTPErrorIch habe verschiedene Möglichkeiten ausprobiert, um es anzuzeigen, aber am Endeerrors.pyAusnahmeklasse 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.FTPErrorWird angezeigt.
__name__Das Umschreiben von Attributen ist nicht üblich. Wenn Sie komplexen Code schreiben,urllib83/__init__.pyEs 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