3 fonctionnalités Python 3.2 toujours d’actualité

  • FrançaisFrançais



  • Il s’agit du troisième article d’une série sur les fonctionnalités apparues pour la première fois dans une version de Python 3.x. Certaines de ces versions de Python sont disponibles depuis un certain temps. Par exemple, Python 3.2 a été publié pour la première fois en 2011, mais certaines des fonctionnalités intéressantes et utiles qui y sont introduites sont encore sous-utilisées. En voici trois.

    sous-commandes argparse

    le argparse Le module est apparu pour la première fois dans Python 3.2. Il existe de nombreux modules tiers pour l’analyse de la ligne de commande. Mais le intégré argparse module est plus puissant que ce que beaucoup lui attribuent.

    Documenter tous les tenants et aboutissants de argparse prendrait sa propre série d’articles. Pour un petit avant-goût, voici un exemple de la façon dont vous pouvez faire des sous-commandes avec argparse.

    Imaginez une commande avec deux sous-commandes: negate, qui prend un argument, et multiply ce qui en prend deux:

    $ computebot negate 5
    -5
    $ computebot multiply 2 3
    6

    import argparse

    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    le add_subparsers() méthodes crée un objet auquel vous pouvez ajouter des sous-commandes. La seule astuce à retenir est que vous devez ajouter quelle sous-commande a été appelée via un set_defaults():

    negate  = subparsers.add_parser("negate")
    negate.set_defaults(subcommand="negate")
    negate.add_argument("number", type=float)

    multiply  = subparsers.add_parser("multiply")
    multiply.set_defaults(subcommand="multiply")
    multiply.add_argument("number1", type=float)
    multiply.add_argument("number2", type=float)

    Un de mes favoris argparse car il sépare l’analyse de l’exécution, le test de la logique d’analyse est particulièrement agréable.

    parser.parse_args(["negate", "5"])
        Namespace(number=5.0, subcommand='negate')
    parser.parse_args(["multiply", "2", "3"])
        Namespace(number1=2.0, number2=3.0, subcommand='multiply')

    contextlib.contextmanager

    Les contextes sont un outil puissant en Python. Alors que beaucoup utiliser eux, écrire un nouveau contexte semble souvent être un art sombre. Avec le contextmanager décorateur, tout ce dont vous avez besoin est un générateur one-shot.

    Ecrire un contexte qui imprime le temps qu’il a fallu pour faire quelque chose est aussi simple que:

    import contextlib, timeit

    @contextlib.contextmanager
    def timer():
        before = timeit.default_timer()
        try:
            yield
        finally:
            after = timeit.default_timer()
            print("took", after - before)

    Et vous pouvez l’utiliser avec seulement:

    import time

    with timer():
        time.sleep(10.5)

        took 10.511025413870811

    Parfois, la mise en cache résulte d’une fonction en mémoire a du sens. Par exemple, imaginez le problème classique: “De combien de façons pouvez-vous faire de la monnaie pour un dollar avec des quarts, des dix sous, des nickels et des cents?”

    Le code pour cela peut être d’une simplicité trompeuse:

    def change_for_a_dollar():
        def change_for(amount, coins):
            if amount == 0:
                return 1
            if amount < 0 or len(coins) == 0:
                return 0
            some_coin = next(iter(coins))
            return (
                change_for(amount, coins - set([some_coin]))
                +
                change_for(amount - some_coin, coins)
            )
        return change_for(100, frozenset([25, 10, 5, 1]))

    Sur mon ordinateur, cela prend environ 13 ms:

    with timer():
        change_for_a_dollar()

        took 0.013737603090703487

    Il s’avère que lorsque vous calculez le nombre de façons dont vous pouvez faire quelque chose comme faire de la monnaie à partir de 50 cents, vous utilisez les mêmes pièces à plusieurs reprises. Vous pouvez utiliser lru_cache pour éviter de recalculer cela encore et encore.

    import functools

    def change_for_a_dollar():
        @functools.lru_cache
        def change_for(amount, coins):
            if amount == 0:
                return 1
            if amount < 0 or len(coins) == 0:
                return 0
            some_coin = next(iter(coins))
            return (
                change_for(amount, coins - set([some_coin]))
                +
                change_for(amount - some_coin, coins)
            )
        return change_for(100, frozenset([25, 10, 5, 1]))

    with timer():
        change_for_a_dollar()

        took 0.004180959425866604

    Une triple amélioration pour le coût d’une ligne. Pas mal.

    Bienvenue en 2011

    Bien que Python 3.2 soit sorti il ​​y a 10 ans, beaucoup 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

    N'oubliez pas de voter pour cet article !
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading...

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée.