Ce que Python 3.3 a fait pour améliorer la gestion des exceptions dans votre code


  • FrançaisFrançais


  • Ceci est le quatrième d’une série d’articles sur les fonctionnalités apparues pour la première fois dans une version de Python 3.x. Python 3.3 a été publié pour la première fois en 2012, et même s’il est sorti depuis longtemps, la plupart des fonctionnalités qu’il a introduites sont sous-utilisées et plutôt intéressantes. En voici trois.

    céder de

    le yield mot-clé a rendu Python beaucoup plus puissant. Comme on pouvait s’y attendre, tout le monde a commencé à l’utiliser pour créer tout un écosystème d’itérateurs. le itertools module et le plus-itertools Les packages PyPI ne sont que deux exemples.

    Parfois, un nouveau générateur voudra utiliser un générateur existant. À titre d’exemple simple (bien que quelque peu artificiel), imaginez que vous vouliez énumérer toutes les paires de nombres naturels.

    Une façon de le faire est de générer toutes les paires dans l’ordre de sum of pair, first item of pair. Mettre en œuvre cela avec yield from est naturel.

    le yield from <x> mot-clé est l’abréviation de:

    for item in x:
        yield item

    import itertools

    def pairs():
        for n in itertools.count():
            yield from ((i, n-i) for i in range(n+1))

    list(itertools.islice(pairs(), 6))
        [(0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0)]

    Packages d’espaces de noms implicites

    Imaginez une entreprise fictive appelée Parasol qui fabrique un tas de choses. Une grande partie de son logiciel interne est écrit en Python. Bien que Parasol ait open source une partie de son code, une partie est trop propriétaire ou spécialisée pour l’open source.

    L’entreprise utilise un serveur DevPI interne pour gérer les packages internes. Cela n’a pas de sens pour chaque programmeur Python chez Parasol de trouver un nom inutilisé sur PyPI, donc tous les packages internes sont appelés parasol.<business division>.<project>. En observant les meilleures pratiques, les développeurs veulent que les noms des packages reflètent ce système de dénomination.

    C’est important! Si le colis parasol.accounting.numeric_tricks installe un module de niveau supérieur appelé numeric_tricks, cela signifie que personne qui dépend de ce package ne pourra utiliser un package PyPI appelé numeric_tricks, peu importe à quel point c’est astucieux.

    Cependant, cela laisse aux développeurs un dilemme: quel package possède le parasol/__init__.py déposer? La meilleure solution, à partir de Python 3.3, est de faire parasol, et probablement parasol.accounting, être packages d’espace de noms, qui n’ont pas le __init__.py déposer.

    Suppression du contexte d’exception

    Parfois, une exception au milieu d’une récupération à partir d’une exception est un problème, et avoir le contexte pour le tracer est utile. Cependant, parfois ce n’est pas le cas: l’exception a été gérée et la nouvelle situation est une condition d’erreur différente.

    Par exemple, imaginez qu’après avoir échoué à rechercher une clé dans un dictionnaire, vous voulez échouer avec un ValueError() s’il ne peut pas être analysé:

    import time

    def expensive_analysis(data):
        time.sleep(10)
        if data[0:1] == ">":
            return data[1:]
        return None

    Cette fonction prend beaucoup de temps, donc lorsque vous l’utilisez, vous souhaitez mettre en cache les résultats:

    cache = {}

    def last_letter_analyzed(data):
        try:
            analyzed = cache[data]
        except KeyError:
            analyzed = expensive_analysis(data)
            if analyzed is None:
                raise ValueError("invalid data", data)
            cached[data] = analyzed
        return analyzed[-1]

    Malheureusement, quand il y a un manque de cache, le traçage a l’air moche:

    last_letter_analyzed("stuff")
        ---------------------------------------------------------------------------

        KeyError                                  Traceback (most recent call last)

        <ipython-input-16-a525ae35267b> in last_letter_analyzed(data)
              4     try:
        ----> 5         analyzed = cache[data]
              6     except KeyError:

        KeyError: 'stuff'

    Lors de la gestion de l’exception ci-dessus, une autre exception se produit:

        ValueError                                Traceback (most recent call last)

        <ipython-input-17-40dab921f9a9> in <module>
        ----> 1 last_letter_analyzed("stuff")
       

        <ipython-input-16-a525ae35267b> in last_letter_analyzed(data)
              7         analyzed = expensive_analysis(data)
              8         if analyzed is None:
        ----> 9             raise ValueError("invalid data", data)
             10         cached[data] = analyzed
             11     return analyzed[-1]

        ValueError: ('invalid data', 'stuff')

    Si tu utilises raise ... from None, vous pouvez obtenir des traces beaucoup plus lisibles:

    def last_letter_analyzed(data):
        try:
            analyzed = cache[data]
        except KeyError:
            analyzed = expensive_analysis(data)
            if analyzed is None:
                raise ValueError("invalid data", data) from None
            cached[data] = analyzed
        return analyzed[-1]

    last_letter_analyzed("stuff")
        ---------------------------------------------------------------------------

        ValueError                                Traceback (most recent call last)

        <ipython-input-21-40dab921f9a9> in <module>
        ----> 1 last_letter_analyzed("stuff")
       

        <ipython-input-20-5691e33edfbc> in last_letter_analyzed(data)
              5         analyzed = expensive_analysis(data)
              6         if analyzed is None:
        ----> 7             raise ValueError("invalid data", data) from None
              8         cached[data] = analyzed
              9     return analyzed[-1]

        ValueError: ('invalid data', 'stuff')

    Bienvenue en 2012

    Bien que Python 3.3 soit sorti il ​​y a près de dix ans, nombre de ses fonctionnalités sont toujours intéressantes et sous-utilisées. Ajoutez-les à votre boîte à outils si vous ne l’avez pas déjà fait.

    Source

    La Rédaction

    L'équipe rédactionnnelle du site

    Pour contacter personnellement le taulier :

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Copy code