Facilitez la compréhension de l'affichage des exceptions du module Python

Récemment, je me demandais comment rendre l'affichage des exceptions de module en Python plus facile à comprendre, mais j'ai trouvé la meilleure méthode, alors je l'ai résumée. Tout d'abord, passons en revue la méthode générale de définition des exceptions de module.

Méthode générale

Comme situation concrète, considérons la situation d'écriture du module urllib83 constitué de la fonction ʻurllib83.urlopen () `en Python 3.3. urllib83 signifie le 83ème module urllib, mais je suis désolé si un module standard avec le même nom apparaît dans le futur.

En dehors de cela, supposons que ce module se compose des trois fichiers suivants.

urllib83/__init__.py
         ftp.py
         http.py

Si vous écrivez ʻurllib83.urlopen () autant que vous le pouvez, cela devrait ressembler à ceci.

__init__.py


from .ftp import ftpopen
from .http import httpopen


def urlopen(url):
    if url.startswith("ftp://"):
        return ftpopen(url)
    else:
        return httpopen(url)

Ensuite, supposons que ce module a des classes d'exception ʻurllib83.FTPError et ʻurllib83.HTTPError, qui héritent toutes deux de la classe d'exception de base ʻurllib83.Urllib83Error. Si vous implémentez ces trois classes d'exception docilement, dans ʻurllib83 / __ init __. Py,

urllib83/__init__.py


class Urllib83Error(Exception):
    pass


class FTPError(Urllib83Error):
    pass


class HTTPError(Urllib83Error):
    pass

Je pense que ce sera défini comme, mais il y a un problème avec cette méthode. ʻUrllib83.FTPError est naturellement déclenché dans ʻurllib83 / ftp.py, donc ftp.py lèvera FTPError,

urllib83/ftp.py


from . import FTPError

def ftpopen(url):
    ...
    raise FTPError

Il est utilisé en important comme, mais comme mentionné ci-dessus, __init __. Py importe ftpopen () from ftp.py. À ce rythme, «__init __. Py» et «ftp.py» s'importeront mutuellement, causant le problème de l'importation circulaire.

Donc, en général, pour éviter ce problème, ajoutez un fichier appelé ʻurllib83 / errors.py` et faites-le comme suit.

urllib83/errors.py


class Urllib83Error(Exception):
    pass

class FTPError(Urllib83Error):
    pass

class HTTPError(Urllib83Error):
    pass

Chaque fichier autre que ʻerrors.py`

__init__.py


from .errors import Urllib83Error, FTPError, HTTPError

__all__ = ['Urllib83Error', 'FTPError', 'HTTPError']

Importez la classe d'exceptions requise comme dans. (Remarque:__all__A besoin de la ligne__init__.pyseulement. )

__init__.pyImporte également la classe d'exception, donc le côté utilisant le module urllib83 également

client.py


from urllib83 import urlopen, Urllib83Error

try:
    urlopen(url)
except Urllib83Error:
    pass

Vous pouvez utiliser des exceptions de module comme celle-ci. Il n'y a rien de mal à cela.

##Qu'est-ce qui ne va pas?## Ce qui m'intéressait, c'est que le côté utilisant le module urllib83 a essayé...Sans utiliser l'instruction excepturllib83.urlopen() Quand vous appelez. urllib83.FTPErrorLorsque cela se produit, le suivi s'affiche comme indiqué ci-dessous.

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
>>>

Dans la dernière ligneurllib83.FTPErrorne pas,urllib83.errors.FTPErrorEst affiché. C'est un problème,urllib83.FTPErrorJe suis d'avis qu'il devrait être affiché.

Cependant, le point de vue général des gens de Pythonista est que "je n'ai aucune idée du problème dans cet affichage." La raison est

La documentation du module urllib83urllib83.FTPErrorSe produira, et l'utilisateur dira dans la clause except,except urllib83.FTPError:Vous pouvez compléter l'exception qui s'est produite par écrit. Le problème n'existe nulle part car il fonctionne selon les spécifications décrites dans la documentation

est ce qu'ils ont dit. D'un autre côté, mon contre-argument à cela est

L'utilisateur du module urllib83urllib83.errors.FTPErrorA été mentionné dans la documentation du module urllib83 lorsque j'ai effectivement rencontré l'indicationurllib83.FTPErrorN'est-ce pas trop cher de le savoir? Depuis le début,urllib83.FTPErrorEst plus facile à comprendre et convivial, vous devriez donc faire quelque chose à ce sujet.

C'est.

##Solution## urllib83.FTPErrorJ'ai essayé différentes manières de l'afficher, mais à la finerrors.pyClasse d'exception avec

errors.py


_SAVED_NAME = __name__
__name__ = __package__
# __name__ = "urllib83" # Cliquez ici pour Python 3.2


class Urllib83Error(Exception):
    pass


class FTPError(Urllib83Error):
    pass


class HTTPError(Urllib83Error):
    pass

__name__ = _SAVED_NAME

Je suis arrivé à la conclusion qu'il semble préférable de le définir comme.

Le point est__name__Réécrivez temporairement le contenu de l'attribut et restaurez-le lorsque la classe d'exception a été définie. Lorsqu'une exception se produit, ce qui suit s'affiche.

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
>>>

Correctementurllib83.FTPErrorEst affiché.

__name__La réécriture des attributs n'est pas courante, et si vous écrivez du code complexe,urllib83/__init__.pyIl peut y avoir une différence par rapport à la définition dans, donc__name__Nous vous recommandons vivement d'éviter autant que possible les traitements compliqués lors de la réécriture des attributs. puis,__name__N'oubliez pas d'annuler les attributs.

##finalement## Jusqu'à présent, nous n'avons trouvé aucun problème avec cette méthode, mais si vous remarquez des problèmes, veuillez nous en informer dans les commentaires. Personnellement, n'y a-t-il pas quelque chose qui cloche dans l'environnement de développement intégré? Je suis particulièrement inquiet à ce sujet.

Recommended Posts

Facilitez la compréhension de l'affichage des exceptions du module Python
14 quiz pour comprendre la portée étonnamment compliquée de Python
Colorez les erreurs Python (traces de pile) pour les rendre plus faciles à comprendre
2015-11-26 python> Afficher la liste des fonctions du module> import math> dir (math)
[python] Une note que j'ai commencé à comprendre le comportement de matplotlib.pyplot
Conseils pour faciliter la lecture des documents d'audition Python
[Python] Comment afficher des nombres aléatoires (module aléatoire)
[Python3] Comprendre les bases de Beautiful Soup
Passez le chemin du module python importé
Créer un diagramme de relations des modules Python
Vérifiez le chemin du module importé Python
[Python3] Comprendre les bases des opérations sur les fichiers
[Python] Comment changer le format de la date (format d'affichage)
Copiez la liste en Python
[Python] Une compréhension approximative du module de journalisation
Essayez d'utiliser le module de collections (ChainMap) de python3
Notes de connaissances nécessaires pour comprendre le framework Python
Je veux afficher la progression en Python!
le zen de Python
Un moyen simple de vérifier la source des modules Python
Le mur lors du passage du service Django de Python 2.7 à la série Python 3
Essayez de créer un module Python en langage C
Comment obtenir le nombre de chiffres en Python
Un mémo pour comprendre visuellement l'axe des pandas.
Comment utiliser Raspeye Relay Module Python
[python] Récupère la liste des classes définies dans le module
[python] option pour désactiver la sortie de click.progressbar
Je veux bien comprendre les bases de Bokeh
Utilisons la version Python du module API Confluence.
Écrire des données dans KINTONE à l'aide du module de requêtes Python
[Python] Résumé de la façon de spécifier la couleur de la figure
Comment accéder à la variable globale du module importé
Comprendre l'état de la perte de données - Python vs R
[Introduction à Python] Utilisation basique de la bibliothèque matplotlib
Pour faire l'équivalent de Ruby ObjectSpace._id2ref en Python
Entièrement traduit le site du "Guide de l'auto-stoppeur de Python"
Python Open CV a essayé d'afficher l'image sous forme de texte.
Note Python: Le mystère de l'attribution d'une variable à une variable
Déployez la page de gestion en production pour faciliter la maintenance.
J'ai essayé de résumer les opérations de chaîne de Python
Conseils aux débutants en Python pour utiliser l'exemple Scikit-image pour eux-mêmes 7 Comment créer un module
L'arrière-plan des caractères de l'image texte est surexposé pour faciliter la lecture.
Une note de malentendu lors de la tentative de chargement de l'intégralité du module self-made avec Python3
J'ai essayé de trouver l'entropie de l'image avec python
[Python] Modifier le contrôle du cache des objets téléchargés sur Cloud Storage
Essayez d'obtenir la liste des fonctions du paquet Python> os
Vers la retraite de Python2
Essayez de comprendre Python soi
La première API à créer avec le framework Python Djnago REST
Connaissances minimales pour démarrer avec le module de journalisation Python
À propos du module Python venv
Vous qui coloriez le journal pour le rendre plus facile à voir
L'histoire de l'introduction de Jedi (package de complétion automatique de python) dans emacs
Mise à jour automatique du module Python
Afficher à l'aide du module python du backend mobile Nifty Cloud
[Super facile! ] Comment afficher le contenu des dictionnaires et des listes incluant le japonais en Python