Xavier Lamorlette

Python : éléments de syntaxe avancée

Sommaire :

Extraction et empaquettement des arguments

Extraction des arguments : unpacking

Pour passer des arguments à une fonction, on peut utiliser * sur une liste (souvent nommée *args), ou ** sur un dictionnaire (souvent nommé **kwargs).

def toto(a, b): ...

args = (1, 2)
toto(*args)

kwargs = {'b': 2, 'a': 1}
toto(**kwargs)

Empaquettement des arguments : packing

À l'inverse, on peut regrouper les arguments d'une fonction dans une liste et un dictionnaire :

def toto(*args, **kwargs): ...
    print(f"positional arguments: {args}")
    print(f"keyword arguments: {kwargs}")

toto(1, 2, tata=3, titi=4)

→
positional arguments: (1, 2)
keyword arguments: {'tata': 3, 'titi': 4}

Générateurs

Une fonction qui utilise yield est une fonction génératrice. Elle retourne un générateur :

def arithmetic_generator(n_max):
    x = 0
    n = 0
    while n <= n_max:
       yield x
       x += 12
       n += 1

for x in arithmetic_generator(10):
    …

Expression génératrice

Utiliser des parenthèses à la place des crochets d'une compréhension de liste crée un générateur qui évite le stockage dans une liste temporaire :

tata = (item for item in toto if condition(item))
for item in tata:
   …

Classe itérable

Pour rendre une classe itérable, le plus simple est d'implémenter la méthode __iter__() comme une fonction génératrice :

class A:
    def __iter__(self):
        …
        yield …

Gestionnaires de contexte

Un gestionnaire de contexte est une classe implémentant les méthodes __enter__() et __exit__() :

class File():
    def __init__(self, filename):
        self._file = open(filename, 'w')

    def __enter__(self):
        return self._file

    def __exit__(self, type, value, traceback):
        self._file.close()

with File("toto.txt") as file:
    file.write("toto")
from time import time

class Timer():
    def __init__(self, name):
        self._name = name

    def __enter__(self):
        self._start = time()

    def __exit__(self, type, value, traceback):
        milliseconds = (time() - self._start) * 1000
        print(f"{self._name}: {milliseconds} ms")

with Timer("toto"):
    …

@contextmanager

On peut créer un gestionnaire de contexte avec @contextmanager et un yield :

from contextlib import contextmanager
from time import time

@contextmanager
def timer(name):
    start = time()
    yield
    milliseconds = (time() - start) * 1000
    print(f"{name}: {milliseconds} ms")

with timer("toto"):
    …

La dernière mise à jour de cette page date d'avril 2023.

Le contenu de ce site est, en tant qu'œuvre originale de l'esprit, protégé par le droit d'auteur.
Pour tout commentaire, vous pouvez m'écrire à xavier.lamorlette@gmail.com.