3 fonctionnalités Python 3.2 toujours d’actualité

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 argparseparser = 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 timewith 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 functoolsdef 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.